from gtts import gTTS
import os
from newspaper import Article
from bs4 import BeautifulSoup as bs
import requests
import sqlite3
from sqlite3 import Error

# DB funcs
def create_connection(path):
    """Creates connection to the SQLite database"""
    conn = None
    try:
        conn = sqlite3.connect(path)
        print("Connection to SQLite DB successful")
    except Error as e:
        print(f"The error '{e}' occurred")
    return conn

def execute_query(conn, query, data_tuple=()):
    """Executes SQL query for creating/populating a table"""
    cursor = conn.cursor()
    try:
        cursor.execute(query, data_tuple)
        conn.commit()
        if query == create_books_table:
            print(f"Table was created successfully")
        elif query == insert_into_books_table:
            print(f"Values were inserted successfully")
        else:
            print(f"Query {query} executed successfully")
    except Error as e:
        print(f"The error '{e}' occurred")

create_books_table = """
CREATE TABLE IF NOT EXISTS books (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    book_title TEXT NOT NULL UNIQUE ON CONFLICT FAIL,
    url_address TEXT NOT NULL,
    author_name TEXT NOT NULL);
"""
insert_into_books_table = """
INSERT INTO books
    (book_title, url_address, author_name)
    VALUES (?, ?, ?);
"""

def get_titles():
    """Executes SELECT query to show a book list"""
    with conn:
        cursor.execute("""SELECT id, book_title, author_name FROM books""")
        result = cursor.fetchall()
        for line in result:
            print(f'{line[0]}) {line[1]} (by {line[2]})')

def user_choise():
    """"Choose a book from list"""
    user_input = input('Please choose a book title inputting the number: ')
    try:
        with conn:
            cursor.execute("""SELECT * FROM books WHERE id = ?""", [int(user_input)])
            result = cursor.fetchone()
            user_chosen_book = result[1]
            book_url = result[2]
            book_author = result[3]
            print(f'You have chosen "{user_chosen_book}" written by {book_author}')
            return user_chosen_book, book_url, book_author
    except:
        print("Can't find the book in my database. Try again")
        return user_choise()

# parse funcs
def title_url_author_parser():
    """"Parse book title, url address and author name and insert into SQL Database"""
    for a in soup.findAll('a', href=True, title=True):
        book_title = a['title']
        url = a['href']
        try:
            author_name = bs(requests.get(url).content, "lxml").find('span', class_='entry-tags').text
        except:
            author_name = 'unknown author'
        execute_query(conn, insert_into_books_table, (book_title, url, author_name))
    print('The table is now complete')

def text_parser(book_info):
    """"Parse user chosen book summary"""
    book_summary = Article(book_info[1], language='en')
    book_summary.download()
    book_summary.parse()
    book_text = f'{book_info[0]}\nby {book_info[2]}\n\n{book_summary.text}'
    return book_text

# funcs for making text and audio files
def make_text(title, content):
    """"Make text file"""
    filename = f'Summaries/{title.lower().replace(" ", "_")}.txt'
    os.makedirs(os.path.dirname(filename), exist_ok=True)
    with open(filename, 'w', encoding="utf-8") as text_file:
        text_file.write(content)
    print('The text file was successfully saved ')

def make_audio(title, content):
    """"Make audio file"""
    speech = gTTS(text=content, lang='en')
    filename = f'Audios/{title.lower().replace(" ", "_")}.mp3'
    os.makedirs(os.path.dirname(filename), exist_ok=True)
    print('Saving the audio file. Please wait for a while')
    speech.save(filename)
    print('The audio file was successfully saved')
    # os.system(filename)

# user input funcs
def choose_another_book():
    """"Let user choose another book from a list"""
    while True:
        user_answer = input('Would you like to pick another book? Input yes/no: ')
        if user_answer.lower() in ['нет', 'no']:
            print("Got it. I'm finishing up the program. Good luck!")
            break
        elif user_answer.lower() in ['да', 'yes']:
            main_process()
        else:
            return choose_another_book()

def text_or_audio(book_info, content):
    """"Ask user whether he/she wants to save text or audio file"""
    user_input = input('Save content to a text or audio file? Input text/audio: ')
    if user_input.lower() == 'текст' or user_input.lower() == 'text':
        make_text(book_info[0], content)
    elif user_input.lower() == 'аудио' or user_input.lower() == 'audio':
        make_audio(book_info[0], content)
    else:
        print("Didn't get it...")
        text_or_audio(book_info, content)
    choose_another_book()

def main_process():
    get_titles()
    book_info = user_choise()
    text_parser(book_info)
    content = text_parser(book_info)
    text_or_audio(book_info,content)

#************************************** starting the programm **********************************************************

site_url = 'https://www.booksummary.net/summaries/'
r = requests.get(site_url)
soup = bs(r.content, "lxml")
numbers_of_books = len(soup.findAll('a', href=True, title=True))
conn = create_connection('books.db')
cursor = conn.cursor()

try:
    is_books_table_empty = cursor.execute("""SELECT COUNT(*) FROM books; """).fetchall()
    if is_books_table_empty[0][0] == numbers_of_books:
        print('Ready to work')
        main_process()
    elif is_books_table_empty[0][0] < numbers_of_books:
        print('Table is not full. Starting to add data into the table...')
        title_url_author_parser()
        main_process()
except:
    print("Books table doesn't exist")
    execute_query(conn, create_books_table)
    title_url_author_parser()
    main_process()

conn.close()


import torch
import numpy as np
import hydra
import torch.utils.data as data
import os
from utils.virtualview_loader import VirtualviewScannetDataset
from utils.realview_loader import RealviewScannetDataset, collate_image
from utils.fusion_2d_3d import Fusioner
from utils.miou import miou_2d, miou_3d
from tqdm import tqdm

class Pipeline3D:
    """
    A pipeline supports 3D inference.
    """
    def __init__(self, cfg):
        self.cfg = cfg
        print('Use visdom:', cfg.visdom.use)
        print('Use virtual view:', not cfg.dataset.real_view)

    def inference(self):
        """
        Use 2D segmentation model to do 3D inference, based on Fusion Algorithm.
        """
        device = self.get_device()

        model_path = self.cfg.evaluation.model_path

        model = self.get_model(model_path).to(device)

        scene_dataset = self.get_scene_dataset(
            mode='train',
            use_transform=True)

        # for scene_id in range(len(scene_dataset)):
        for scene_id in range(1):
            single_scene_data = scene_dataset[scene_id]

            image_dataset = single_scene_data['imgset']
            pc_xyz = single_scene_data['point_cloud_xyz'].to(device)
            pc_semantic_label = single_scene_data['semantic_label'].to(device)
            try:
                intrinsic_depth = single_scene_data['intrinsic_depth'].to(device)
            except:
                intrinsic_depth = single_scene_data['intrinsic'].to(device)

            # img loader
            image_dataloader = data.DataLoader(
                dataset=image_dataset,
                batch_size=self.cfg.data_loader.batch_size,
                shuffle=False,
                num_workers=self.cfg.data_loader.num_workers,
                collate_fn=collate_image)

            # a machine able to fuse 2d and 3d
            collection_method = 'knn'
            fusion_machine = Fusioner(point_cloud=pc_xyz,
                                intrinsic_depth=intrinsic_depth,
                                collection_method=collection_method, # average, knn
                                use_gt=False)

            # collect features
            # process_bar = tqdm(total=len(image_dataset)) # show process
            batch_size = self.cfg.data_loader.batch_size

            for idx, batch in enumerate(image_dataloader): # loop over image
                with torch.no_grad():
                    imgs = batch['color_img'].to(device)
                    depth_imgs = batch['depth_img']
                    pose_matrixs = batch['pose_matrix']
                    semantic_labels = batch['semantic_label'].to(device)

                    preds = model(imgs)

                    preds = torch.softmax(preds, dim=1)

                    for i in range(imgs.shape[0]): #single data point
                        depth_img = depth_imgs[i].to(device)
                        img = imgs[i].to(device)
                        pose_matrix = pose_matrixs[i].to(device)
                        pred = preds[i].to(device)

                        fusion_machine.projection(depth_img=depth_img,
                                                pose_matrix=pose_matrix,
                                                feature_img=pred,
                                                threshold=5)

                # process_bar.update(batch_size)
            if collection_method=='average':
                pc_features = fusion_machine.get_features()
                pc_pred_label = torch.max(pc_features, dim=1).indices
            elif collection_method=='knn':
                pc_features = fusion_machine.get_features()
                pc_pred_label = torch.tensor(pc_features)

            # get MIOU
            MIOU = miou_3d(pc_pred_label, pc_semantic_label)

            print("MIOU:", MIOU)

    def get_model(self, model_path=None):
        # load model
        if self.cfg.model.model_name=='deeplabv3+':
            from modeling.deeplab import DeepLab
            backbone = self.cfg.model.backbone
            num_classes = self.cfg.model.num_classes
            output_stride = self.cfg.model.output_stride
            model = DeepLab(backbone=backbone, num_classes=num_classes,
                            output_stride=output_stride)
        elif self.cfg.model.model_name=='unet':
            from unet import UNet
            num_channels = self.cfg.model.num_channels
            num_classes = self.cfg.model.num_classes
            model = UNet(n_channels=num_channels, n_classes=num_classes)

        # load pretrained model
        if model_path is None:
            if self.cfg.model.pretrain:
                pretrain_path = self.cfg.model.pretrained_model_path
                model.load_state_dict(torch.load(pretrain_path))

        # load self path
        if model_path is not None:

            model.load_state_dict(torch.load(model_path))

        print('Model name:', self.cfg.model.model_name)
        return model

    def get_device(self):
        device = None
        if self.cfg.device!='cpu':
            device = torch.device(self.cfg.device)
        else:
            device = torch.device('cpu')
        return device

    def get_scene_dataset(self, mode='train', use_transform=True):
        if self.cfg.dataset.real_view: # use real view
            dataset = RealviewScannetDataset(self.cfg, mode=mode, use_transform=use_transform)
        else: # use virtual view
            dataset = VirtualviewScannetDataset(self.cfg, mode=mode, use_transform=use_transform)

        return dataset

@hydra.main(config_path='config', config_name='config')
def main(cfg):
    ppl = Pipeline3D(cfg)
    ppl.inference()

if __name__=='__main__':
    main()


import nltk

"""list of words to remove meaningless words"""

words = set(nltk.corpus.words.words())

def meaningful_check(word):
    word = word.lower()
    word_length = len(word.split(" "))
    if((word in words and word_length==1) or word_length>1):
        return True
    else:
        return False


import numpy as np
from ...graph.Gl import gl

############# BASIC PLOTS #####################################
def plot_series(self, axes = None, series_name = "Close", *args, **kwargs):
    time_series = self[series_name];
    timestamps = self.timestamps

    # TODO: Merge of dictionaries to be able to add properties externally
    labels = ["Price", "", ""]
    legend = [series_name]

    if (series_name == "Volume"):
        drawings =  gl.stem(timestamps,time_series, legend = legend, *args, **kwargs)
    else:
        drawings = gl.plot(timestamps,time_series, axes = axes, legend = legend,
                           *args, **kwargs)
    return drawings

def plot_indicator(self, axes = None, indicator_name = "SMA", *args, **kwargs):
    indicator_output = self.indicator(name = indicator_name, *args, **kwargs)
    timestamps = self.timestamps

    if indicator_name in ["SMA","EMA","WMA","HMA","HMAg"]:
        drawings = gl.plot(timestamps, indicator_output, axes = axes, legend = [indicator_output.name])
    elif indicator_name in ["MOM","ROC","RETURN","GAP"]:
        drawings = gl.stem(timestamps, indicator_output, axes = axes, legend = [indicator_output.name])
    elif indicator_name == "MACD":
        drawings = _plot_MACD(indicator_output, axes = axes, color_mode = 1)
    elif indicator_name in ["RSI"]:
        drawings = _plot_oscillator(indicator_output[indicator_output.columns[1]], axes = axes, color_mode = 1)
    return drawings

def plot_barchart(self,*args, **kwargs):
    if (self.df.shape[0] >0):
        drawings = gl.barchart(self.df,*args, **kwargs)
        return drawings

def plot_candlesticks(self, *args, **kwargs):
    drawings = gl.candlestick(self.df,*args, **kwargs)
    return drawings

"""
######################## INTERNAL COMPLEX PLOTTING #############
"""

def _plot_MACD(MACD_df, axes = None, color_mode = 1):
    if (color_mode == 0):
        fillcolor = '#00ffe8'
        indCol = '#c1f9f7'
        posCol = '#386d13'; negCol = '#8f2020'
        bg_color = '#07000d'; col_axis = 'w'
        col_spines = "#5998ff"
    elif (color_mode == 1):
        fillcolor = '#00ffe8'
        indCol = '#c1f9f7'
        posCol = '#386d13'; negCol = '#8f2020'
        bg_color = '#07000d'; col_axis = 'k'
        col_spines = "#5998ff"

    timestamps = MACD_df.index
    MACD = MACD_df["MACD"]
    MACDsign= MACD_df["MACDsign"]
    MACDdiff= MACD_df["MACDdiff"]

    gl.plot(timestamps, MACD, axes=axes,color='#4ee6fd', lw=2)
    gl.plot(timestamps, MACDsign, axes = axes, color='#e1edf9', lw=1)
    gl.fill_between(timestamps, MACDdiff, axes = axes, y2 = 0, alpha=0.5) # facecolor=fillcolor, edgecolor=fillcolor)

    ## Format the axis
    gl.color_axis(axes, col_spines, col_axis)
#    axes.set_ylabel('MACD', color='k', fontsize = 15)

def _plot_oscillator(oscillator_series, axes = None, color_mode = 0):
    """
    Plots an oscillator, we need the series name
    """
    if (color_mode == 0):
        indCol = '#c1f9f7'
        posCol = '#386d13'; negCol = '#8f2020'
        bg_color = '#07000d'; col_axis = 'w'
        col_spines = "#5998ff"

    if (color_mode == 1):
        indCol = '#c1f9f7'
        posCol = '#386d13'; negCol = '#8f2020'
        bg_color = '#07000d'; col_axis = 'k'
        col_spines = "#5998ff"

    highline = 70
    lowline = 30

    timestamps = oscillator_series.index
    gl.plot(timestamps, oscillator_series, color = indCol, lw=1.5)

    if axes is None:
        axes = gl.axes

    # Draw some lines !
    axes.axhline(highline, color=negCol)
    axes.axhline(lowline, color=posCol)

    # Fill between the lines !
    # Since rsi has Nan, the inequalities will give a warning, but that is it.
#    warnings.filterwarnings("ignore")
    gl.fill_between(x = timestamps, y1 = oscillator_series, y2 = highline, alpha=0.99,
                    where=(oscillator_series>=highline)) # facecolor=negCol, edgecolor=negCol
    gl.fill_between(x = timestamps, y1 = oscillator_series, y2 = lowline, alpha=0.99,
                    where=(oscillator_series<=lowline)) # , facecolor=posCol, edgecolor=posCol
#    warnings.filterwarnings("always")

    ## Format color and so on.
    axes.set_yticks([lowline,highline])
    axes.yaxis.label.set_color(col_axis)
    gl.color_axis(axes, col_spines, col_axis)

############# Indicator plots #####################################

def scatter_deltaDailyMagic(self):
    ## PLOTS DAILY HEIKE ASHI
    ddelta = self.get_timeSeriesbyName("RangeCO")
    hldelta = self.get_timeSeriesbyName("RangeHL")

    mdelta = self.get_magicDelta()
    labels = ["Delta Magic Scatter","Magic","Delta"]

    gl.scatter(mdelta,ddelta,
               labels = labels,
               legend = [self.symbolID],
               nf = 1)

#    gl.set_subplots(1,1)
    gl.scatter_3D(mdelta,ddelta, hldelta,
                   labels = labels,
                   legend = [self.symbolID],
                   nf = 1)

def plot_TrCrMr(self):
    ## Plots the Three deadly cross thingy.
    timeSeries = self.get_timeSeries()
    TrCrMr = self.get_TrCrMr()
    labels = ["Trio de la Muerte","Time","Price"]
    gl.plot(self.dates,timeSeries,
                  labels = labels,
                  legend = ["Price"],
                  color = "k",nf = 1)

    gl.plot(self.dates,TrCrMr,
                  labels = labels,
                  legend = ["Trio de la Muerte"],
                  color = "b",nf = 0)

def plot_BollingerBands(self, new_figure = 0, L = 21):
    if (new_figure == 1):
        self.new_plot(title = "Bollinger Bands", xlabel = "time", ylabel = "Close")

    SMA = self.get_SMA(L = L)
    BB = self.get_BollingerBand(L = L)

    self.plot_timeSeries()
    gl.plot(self.dates,SMA + BB, legend = ["SMA + BB"], nf = 0)
    gl.plot(self.dates,SMA - BB, legend = ["SMA - BB"], nf = 0)


#!/usr/bin/env python

from __future__ import print_function
from __future__ import division
from builtins import range
from past.utils import old_div
from read_hdf5 import *

T = 1.0
nDTout = 100
DT = old_div(T,float(nDTout))

archive = Archiver.XdmfArchive(".","heat_3d",readOnly=True)

import numpy as np

u = read_from_hdf5(archive.hdfFile,'/u0')
S = np.reshape(u,(np.shape(u)[0],1))
for i in range(1,nDTout+1):
    time_level_to_read=i
    label="/%s%d" % ('u',time_level_to_read)
    print('trying to read from %s ' % label)
    u = read_from_hdf5(archive.hdfFile,label)
    u = np.reshape(u, (np.shape(u)[0],1))
    S = np.append(S,u,axis=1)

U, s, V = np.linalg.svd(S, full_matrices=False)
print('SVD done!')
np.savetxt('SVD_basis', U, delimiter=' ')
np.savetxt('Singular_values', s, delimiter=' ')


import random
import deposits
import constants as c

MONTHLY_SPENDING_THRESHOLDS_BY_TIERS = {
	c.MAXIMUM_TIER: 150,
	c.AVERAGE_TIER: 100,
	c.LIGHT_TIER: 50,
	c.MICRO_TIER: 25,
}

CC_FEES_RATE = 0.002
CC_FEES_FLAT = 0.2

MIN_COST_OF_COFFEE = 2.5
MAX_COST_OF_COFFEE = 20

MIN_COFFEES_PER_MONTH = 1
MAX_COFFEES_PER_MONTH = 19

MEAN_COST_OF_COFFEE = (MIN_COST_OF_COFFEE + MAX_COST_OF_COFFEE) / 2
MEAN_COFFEES_PER_MONTH = (MIN_COFFEES_PER_MONTH + MAX_COFFEES_PER_MONTH) / 2

MIN_COST_OF_COFFEE = 2.5
MAX_COST_OF_COFFEE = 20

MIN_COFFEES_PER_MONTH = 1
MAX_COFFEES_PER_MONTH = 19

DAILY_COFFEE_EXPENSE_LIMIT = 20
MONTHLY_COFFEE_EXPENSE_LIMIT = 250

def calculate_coffees_per_month():
	return max(random.normalvariate(MEAN_COFFEES_PER_MONTH, (MAX_COFFEES_PER_MONTH - MEAN_COFFEES_PER_MONTH) / 3), 0)

def coffee_spending(day, users):
	coffee_expenses = 0
	cc_fees = 0

	# people spending money on coffee
	for i, user in enumerate(users):
		if 'daily_coffee_expenses' not in user:
			users[i]['daily_coffee_expenses'] = 0
		if 'monthly_coffee_expenses' not in user:
			users[i]['monthly_coffee_expenses'] = 0
		if 'max_monthly_coffee_expenses' not in user:
			users[i]['max_monthly_coffee_expenses'] = 0

		# reset monthly coffee expenses
		if day % 30 == 1:
			users[i]['monthly_coffee_expenses'] = 0

		# reset daily coffee expenses
		users[i]['daily_coffee_expenses'] = 0

		coffees_per_month = users[i]['coffees_per_month']

		if random.random() < coffees_per_month / 30:
			cost_of_coffee = min(max(random.normalvariate(MEAN_COST_OF_COFFEE, (MAX_COST_OF_COFFEE - MEAN_COST_OF_COFFEE) / 3), 0), MAX_COST_OF_COFFEE)
			# add credit card fees
			cc_fees += cost_of_coffee * CC_FEES_RATE + CC_FEES_FLAT

			# can't buy if over the daily or monthly limit
			if cost_of_coffee + user['monthly_coffee_expenses'] > MONTHLY_COFFEE_EXPENSE_LIMIT or cost_of_coffee + user['daily_coffee_expenses'] > DAILY_COFFEE_EXPENSE_LIMIT:
				continue

			if user['balance'] >= cost_of_coffee:
				coffee_expenses += cost_of_coffee
				users[i]['monthly_coffee_expenses'] += cost_of_coffee
				users[i]['daily_coffee_expenses'] += cost_of_coffee
				users[i]['balance'] -= cost_of_coffee
			elif user['balance'] > 0:
				coffee_expenses += user['balance']
				users[i]['monthly_coffee_expenses'] += user['balance']
				users[i]['daily_coffee_expenses'] += user['balance']
				users[i]['balance'] = 0

		# upgrade tiers if they reach the spending thresholds
		if users[i]['max_monthly_coffee_expenses'] < users[i]['monthly_coffee_expenses']:
			users[i]['max_monthly_coffee_expenses'] = users[i]['monthly_coffee_expenses']

			if users[i]['max_monthly_coffee_expenses'] >= MONTHLY_SPENDING_THRESHOLDS_BY_TIERS[c.MAXIMUM_TIER]:
				users[i]['tier'] = c.MAXIMUM_TIER
			elif users[i]['max_monthly_coffee_expenses'] >= MONTHLY_SPENDING_THRESHOLDS_BY_TIERS[c.AVERAGE_TIER]:
				users[i]['tier'] = c.AVERAGE_TIER
			elif users[i]['max_monthly_coffee_expenses'] >= MONTHLY_SPENDING_THRESHOLDS_BY_TIERS[c.LIGHT_TIER]:
				users[i]['tier'] = c.LIGHT_TIER
			elif users[i]['max_monthly_coffee_expenses'] >= MONTHLY_SPENDING_THRESHOLDS_BY_TIERS[c.MICRO_TIER]:
				users[i]['tier'] = c.MICRO_TIER

	return coffee_expenses, cc_fees


import re
import numpy as np

def tokenize_net(file):
    f = open(file)
    det = f.read()

    ret = []

    det = det.split("|")

    for l in det:
        ret.append(tokenize_layer(l))

    return ret

def tokenize_layer(l):
    ret = {}
    ins = re.split(r":", re.sub(r"[\n\s]", "", l))
    layerdet = re.split(r"[()]", ins[0])
    ret["ltype"] = layerdet[0]
    if len(layerdet) > 1 and layerdet[1]:
        ret["lspec"] = layerdet[1]

    ret["act"] = ins[1]
    ret["params"] = np.array([i for i in map(float, re.split(r",", ins[2]))])
    ret["dists"] = re.split(r",", ins[3])

    return ret


#!/usr/bin/python

import requests
import datetime
import random
import os, sys
import time
import string

def randomString(stringLength):
    letters = string.ascii_letters
    return ''.join(random.choice(letters) for i in range(stringLength))

if len(sys.argv) != 2:
    exit("usage: {} addr".format(sys.argv[0]))

for user_id in range(1):
    payload = {
        "promiseid": randomString(20),
        "description" : "Как меня зовут?",
        "userid": 346,
        'metrics': "",
        'category': 0,
        'wall_pub': True,
        'story_pub': False,
        'exp_date': 0,
        'pub_date': 0,
        'transactions': []
    }
    print(payload)
    r = requests.post("https://" + sys.argv[1] + "/submitpromise", cert='stunnel.pem', json=payload, verify=False)
    print(r)


from car_file import Car,ElectricCar
my_car = Car("奥迪", "A4", 2013)
my_car.this_year=2020            #方法1对象修改属性值-需要修改对象的属性时必须要通过对象来进行修改，并且修改属性不需要在定义对象时传进去，只需要的属性定义语句中添加类的默认属性和默认值
print(my_car.year)
print(my_car.detection())
your_car=Car("奔驰","c200",2012)
your_car.mod_this_year(2020)     #方法2使用方法定义来进行属性的修改，不需要返回return值，需要进行传入新的参数就可以
print(your_car.detection())
my_tesla=ElectricCar("Tesla","model-s",2017)
print(my_tesla.year)
my_tesla.this_year=2020
my_tesla.battery(100)
print(my_tesla.detection())


import tushare as ts
import os
import time

"""
# 设计一个股票、基金池，监控价格
# 从tushare pro获取数据，绘制股票走势图
# 设定一些监控指标进行计算，例如：
    一个月内最低点、三个月内最低点、半年内最低点、一年内最低点
    一个月内最高点、三个月内最高点、半年内最高点、一年内最高点
    一个月内涨跌幅、三个月内涨跌幅、半年内涨跌幅、一年内涨跌幅
    局部最低点、局部最高点
# 成交量的变化
# 不同时间段的趋势类型，例如震荡、上升、下降
"""

# 使用time获取今天的日期
today = time.strftime('%Y%m%d', time.localtime(time.time()))

# df = ts.get_hist_data('600519', start='2020-01-01', end=today)
# print(df)

# 设置tushare pro的token，用于获取数据
ts.set_token(os.getenv("TS_PRO_TOKEN"))

# 初始化pro接口
pro = ts.pro_api()

# 获取贵州茅台过去三年的日线数据
df = pro.daily(ts_code='600519.SH', start_date='20180101', end_date=today)

# 找到最低点
lowest_price = df['close'].min()
lowest_date = df.loc[df['close'].idxmin(), 'trade_date']

# 输出结果
print('最低价:', lowest_price)
print('日期:', lowest_date)


"""
This script expects you've followed the instructions in https://github.com/chb/py-umls to install UMLS.
"""

import json
from collections import Counter
import sqlite3

from scispacy.umls_semantic_type_tree import construct_umls_tree_from_tsv
umls_tree = construct_umls_tree_from_tsv('data/umls_semantic_type_tree.tsv')  # change to your location

umls_db_path = '/home/dan/projects/py-umls/databases/umls.db'  # change to your location
conn = sqlite3.connect(umls_db_path)
c = conn.cursor()

cui_data = {}
source_counter = Counter()
def_mismatches = set()

st21pv_sources = set(['CPT', 'FMA', 'GO', 'HGNC', 'HPO', 'ICD10',
                      'ICD10CM', 'ICD9CM', 'MDR', 'MSH', 'MTH',
                      'NCBI', 'NCI', 'NDDF', 'NDFRT', 'OMIM',
                      'RXNORM', 'SNOMEDCT_US'])

st21pv_types = set(['T005', 'T007', 'T017', 'T022', 'T031', 'T033', 'T037',
                    'T038', 'T058', 'T062', 'T074', 'T082', 'T091', 'T092',
                    'T097', 'T098', 'T103', 'T168', 'T170', 'T201', 'T204'])

st21pv_types_children = {}
for st in st21pv_types:
    st_node = umls_tree.get_node_from_id(st)
    st_children = set([ch.type_id for ch in umls_tree.get_children(st_node)])
    st21pv_types_children[st] = st_children

RESTRICT_ST21PV = False
NO_DEFS = False

print('Collecting info from \'descriptions\' table ...')
for row_idx, row in enumerate(c.execute('SELECT * FROM descriptions')):

    CUI, LAT, SAB, TTY, STR, STY = row

    source_counter[SAB] += 1

    STY = STY.split('|')
    if LAT != 'ENG':
        continue

    if RESTRICT_ST21PV:
        if SAB not in st21pv_sources:
            continue

        valid_row_sts = []
        for row_st in STY:
            if row_st in st21pv_types:
                valid_row_sts.append(row_st)

            else:
                for st in st21pv_types:
                    if row_st in st21pv_types_children[st]:
                        valid_row_sts.append(st)  # not row_st !
                        break

        if len(valid_row_sts) == 0:
            continue
        else:
            STY = valid_row_sts

        if len(st21pv_types.intersection(set(STY))) == 0:
            continue

    if CUI not in cui_data:
        CUI_info = {}
        CUI_info['SAB'] = SAB
        # CUI_info['TTY'] = TTY
        CUI_info['STY'] = STY

        if NO_DEFS is False:
            CUI_info['DEF'] = []

        CUI_info['STR'] = [STR]
        CUI_info['Name'] = '' # custom

        cui_data[CUI] = CUI_info

    else:
        cui_data[CUI]['STR'].append(STR)

    # source_counter[SAB] += 1

print('# CUIs:', len(cui_data))

if NO_DEFS is False:
    print('Collecting info from \'MRDEF\' table ...')
    for row_idx, row in enumerate(c.execute('SELECT * FROM MRDEF')):
        CUI, AUI, ATUI, SATUI, SAB, DEF, SUPPRESS, CVF = row

        if CUI in cui_data:
            cui_data[CUI]['DEF'].append(DEF)
        else:
            def_mismatches.add(CUI)

print('Preprocessing data ...')
for cui in cui_data.keys():
    cui_data[cui]['Name'] = cui_data[cui]['STR'][0]
    cui_data[cui]['STR'] = list(set(cui_data[cui]['STR'][1:]))

print('Storing data as JSON ...')

fn = 'umls.2017AA.active'
if RESTRICT_ST21PV:
    fn += '.st21pv'
else:
    fn += '.full'

if NO_DEFS:
    fn += '.no_defs'

fn += '.json'

with open(fn, 'w') as json_f:
    json.dump(cui_data, json_f)


# -*- coding: utf-8 -*-
"""
Created on Mon Dec 16 22:24:44 2019

@author: z003vrzk
"""

# Python imports
import sys
import os

# Third party imports
import numpy as np
from sklearn.metrics import (auc_roc_score, recall_score,
                             balanced_accuracy_score, precision_score,
                             recall_score, accuracy_score)

# Local imports
if __name__ == '__main__':
    # Remove the drive letter on windows
    _CWD = os.path.splitdrive(os.getcwd())[1]
    _PARTS = _CWD.split(os.sep)
    # Project dir is one level above cwd
    _PROJECT_DIR = os.path.join(os.sep, *_PARTS[:-1])
    if _PROJECT_DIR not in sys.path:
        sys.path.insert(0, _PROJECT_DIR)

#%%

y_true = np.array([0, 1, 0, 0, 1, 0])
y_pred = np.array([0, 1, 0, 0, 0, 1])
weight = np.array([1, 1, 1, 1, 1, 1])

balanced_accuracy_score(y_true, y_pred)

# Balanced accuracy is the mean of sensitivity and specificity
true_positive = (y_pred == 1) & (y_true == 1)
false_negative = (y_pred == 0) & (y_true == 1)
false_positive = (y_pred == 1) & (y_true == 0)
true_negative = (y_pred == 0) & (y_true == 0)
sensitivity = sum(true_positive) / (sum(true_positive) + sum(false_negative))
specificity = sum(true_negative) / (sum(true_negative) + sum(false_positive))

recall0 = recall_score(y_true, y_pred, pos_label=0)
recall1 = recall_score(y_true, y_pred, pos_label=1)

#%% Testing metrics

y_true = np.array(['ahu','alarm','boiler','chiller','chiller',
                   'exhaust_fan','ahu','ahu','ahu'])
y_pred = np.array(['alarm','ahu','boiler','chiller','chiller',
                   'exhaust_fan','ahu','ahu','ahu'])

# Test accuracy, precision, recall
acc = accuracy_score(y_true, y_pred) # 7 / 9 are correct

"""Precision is ability of estimator to give positive labels to instances
not identified as positive
Precision = TP / (TP + FP)
TP = 7
FP = 2"""
prec = precision_score(y_true, y_pred, average='weighted')

"""Recall is ability of estimator to identify all positive classes
Recall = TP / (TP + FN)
TP = 7
FN = 2"""
rec = recall_score(y_true, y_pred, average='weighted')
rec2 = recall_score(y_true, y_pred, average='weighted', labels=['ahu'])

sum(y_true == y_pred) / len(y_true)


import datetime
import json
from aiohttp import web
from aiohttp.web import Response
from .spider import get_grade
from .decorator import require_info_login
from .mongo_init import mongo_collection
from jsoncensor import JsonCensor

api = web.Application()

def parseQuertString(query_string):
    if query_string:
        keys = []
        vals = []
        for _ in query_string.split('&'):
            keys.append(_.split('=')[0])
            vals.append(_.split('=')[1])
        args = dict(zip(keys, vals))
        xnm = args.get('xnm')  # xnm: 学年 2016,2017...
        xqm = args.get('xqm')  # xqm:第一学期3，第二学期12,第三学期16
        return xnm, xqm
    return "",""

# ====== async view handlers ======
# 有能从学校处查询的成绩一定使用新成绩
# 只有在从学校那里拿不到的时候才使用缓存的
@require_info_login
async def grade_all_api(request, s, sid, ip):
    current_date = datetime.datetime.now().date()
    current_year = current_date.year
    query_string = request.rel_url.query_string
    xnm,xqm=parseQuertString(query_string)
    key = sid + "_" + xnm + "_" + xqm  # 存入mongodb中的键
    # 查本学年成绩
    if (int(xnm) == current_year and xqm == "3" and datetime.date(current_year, 11, 1) < current_date <= datetime.date(current_year, 12, 30)) \
            or (int(xnm) + 1 == current_year and xqm == "3" and datetime.date(current_year, 1, 1) < current_date <= datetime.date(current_year, 3, 1)) \
            or (int(xnm) + 1 == current_year and xqm != "3" and datetime.date(current_year, 5, 1) < current_date <= datetime.date(current_year, 9, 1)):
        gradeList = await get_grade(s, sid, ip, xnm, xqm)
        val = mongo_collection.find_one({"key": key})
        if gradeList:
            return web.json_response(gradeList)
        elif val is not None:
            # 没有爬到数据,并且缓存中有数据，则返回缓存中的数据
            return web.json_response(json.loads(val))
    else:
        #查以往学年成绩
        gradeList = await get_grade(s, sid, ip, xnm, xqm)
        if gradeList:
            mongo_collection.insert_one({"key": key, "val": json.dumps(gradeList)})
            return web.json_response(gradeList)
        else:
            return Response(body=b'', content_type='application/json', status=404)

async def grade_all_api_cache(request):
    headers = request.headers
    req_headers = dict(headers)
    sid = req_headers.get("Sid")
    query_string = request.rel_url.query_string
    xnm, xqm = parseQuertString(query_string)
    key = sid + "_" + xnm + "_" + xqm  # 存入mongodb中的键
    val = mongo_collection.find_one({"key": key})
    if val is not None:
        val.pop('_id')
        return web.json_response(val)
    return Response(body=b'', content_type='application/json', status=404)

# ios cache
async def grade_ios_client_cache(request):
    headers = request.headers
    req_headers = dict(headers)
    sid = req_headers.get("Sid")
    query_string = request.rel_url.query_string
    xnm, xqm = parseQuertString(query_string)

    print("xnm:", xnm, "xqm:", xqm, "sid:", sid)

    key = sid + "_" + xnm + "_" + xqm
    json_data = await request.json()
    cache_string = json_data.get('data') or None
    if cache_string == None:
        return Response(body=b'{"msg":"need json key:data"}', content_type='application/json', status=400)
    mongo_collection.find_one_and_replace({"key": key}, {"key":key,"val":cache_string}, upsert = True)
    return Response(body=b'', content_type='application/json', status=201)

# ====== url --------- maps  ======
api.router.add_route('GET', '/grade/', grade_all_api, name='grade_all_api')
api.router.add_route('GET','/grade/cache/',grade_all_api_cache,name='grade_all_api_cache')
api.router.add_route('POST', '/grade/cache/', grade_ios_client_cache, name='grade_ios_client_cache')
# ==============================


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA, NMF
import os

os.chdir(r"D:\1. stark\anaconda_workspace\no.2\머신러닝 알고리즘과 응용\data")

df = pd.read_csv('data_number_nine.csv', header='infer',encoding='latin1')

print(df.shape)

df.head(5)

def ShowMe(X):
    Y= 1.0 - X
    plt.imshow(Y, cmap='gray')
    plt.show()

X = np.array(df)
ShowMe(X)
print(X)

def reducedPCA(X,nPC):
    pca = PCA(n_components = nPC)
    X_pca = pca.fit_transform(X)
    print(X_pca)
    return pca.inverse_transform(X_pca)

for nPC in [23, 10, 5, 3, 1]:
    Z = reducedPCA(X,nPC)
    # print(Z)
    print( "N# of PCs = " + str(nPC))
    ShowMe(Z)
# print(Z)


#!/usr/bin/env python3
"""
Alarm navigation menu
Tested on windows 10 (Not working at the moment)
Ubuntu 18.04
mac high sierra and Mojave
"""
import datetime
import time
import os

class AlarmMenu:
    """Alarm menu"""

    def __init__(self, alarm_app):
        self.app = alarm_app

    def menu(self):
        """Run menu for user selection input"""
        choice = input("""\
    Alarm Clock APP
    Please choose an option:
    1) Run alarm without date specification
    2) Choose a single day of the week
    3) Turn alarm on during Weekdays
    4) Turn alarm on during Weekends
    9) Load saved settings
    0) Settings
    > """)
        choice_dict = {
            "1": self.quick_start,
            "2": self.normal_mode,
            "3": self.weekday_mode,
            "4": self.weekend_mode,
            "9": self.load_settings,
            "0": self.settings
        }
        if choice_dict.get(choice) is None:
            print("\n\t{} is an Invalid input\n".format(choice))
            self.menu()
        else:
            choice_dict[choice]()

    def quick_start(self):
        """Run alarm app with only alarm time input"""
        self.run_sch()

    def normal_mode(self):
        """
        Select which day or days of the week to run alarm
        Alarm time input also required
        """
        date_choice = self.get_dates()
        self.run_sch(date_choice)

    def weekday_mode(self):
        """
        Run alarm app on weekdays only
        Alarm time input required
        """
        _weekday = [1, 2, 3, 4, 5]
        self.run_sch(_weekday)

    def weekend_mode(self):
        """
        Run alarm app on weekends only
        Alarm time input required
        """
        _weekend = [6, 7]
        self.run_sch(_weekend)

    def load_settings(self):
        """
        Load saved settings
        Schedule, time, ringtone, and volume settings can be saved
        at settings menu
        """
        if self.file_exist() is True and self.file_is_empty() is False:
            with open("settings.txt", "r") as ftxt:
                data = ftxt.read().split("\n")
                if data[0] != "None":
                    date_choice = [int(i) for i in data[0]]
                else:
                    date_choice = None
                if data[1] != "None":
                    time_choice = data[1]
                else:
                    time_choice = None
                if data[2] != "None":
                    ringtone_choice = data[2]
                else:
                    ringtone_choice = None
                if data[3] != "None":
                    volume_choice = data[3]
                else:
                    volume_choice = None
                self.run_sch(choice=date_choice, al_time=time_choice,
                             ringtone=ringtone_choice, vol=volume_choice)
        else:
            print("\n\tNo settings saved!"
                  " Please first set settings at settings menu\n")
            self.menu()

    def settings(self):
        """Settings menu"""
        choice = input("""\
    Select setting options
    1) set schedule settings
    2) set alarm time settings
    3) set ringtone settings
    4) set alarm volume settings
    5) view saved settings
    0) return to main menu
    > """)
        choice_dict = {
            "1": self._set_schedule,
            "2": self._set_time,
            "3": self._set_ringtone,
            "4": self._set_volume,
            "5": self._view_settings,
            "0": self.menu,
        }
        if choice_dict.get(choice) is None:
            print("\n\tInvalid input")
            self.settings()
        else:
            choice_dict[choice]()

    def run_sch(self, choice=None, al_time=None, ringtone=None, vol=None):
        """
        Runs alarm app according to input schedule
        App will sleep until alarm time to prevent uneccessary CPU usage
        to run in the background silently
        """
        alarm_time = self.get_alarm_time(al_time)
        print("\n\tAlarm is ON\n")
        try:
            while True:
                while alarm_time != self.current_time():
                    time.sleep(1)
                if choice is None:
                    self._run_sch(ringtone, vol)
                else:
                    for i in choice:
                        if i == self.current_date().isoweekday() and \
                           alarm_time == self.current_time():
                            self._run_sch(ringtone, vol)
        except KeyboardInterrupt:
            print("\n\tAlarm has been turned OFF")

    def _run_sch(self, ringtone, vol):
        """
        run schedule
        Sleep is implemented if user attempted KeyboardInterrupt
        during alarm time to prevent alarmrm from continuously ringing
        """
        self.app(ringtone, vol)
        print("\n\tAlarm is still ON\n\tPress ctrl + c again to turn off!")
        time.sleep(60)

    @staticmethod
    def current_date():
        """Get current date"""
        return datetime.date.today()

    @staticmethod
    def current_time():
        """Get current time"""
        return str(datetime.datetime.today())[-15:-10]

    def get_alarm_time(self, al_time=None):
        """Set alarm time"""
        if al_time is None:
            hour, minute = None, None
        else:
            hour = al_time[:-3]
            minute = al_time[3:]
        return self._get_hour(hour) + ":" + self._get_minute(minute)

    def _get_hour(self, hour):
        """
        hour must be in 24 hour format
        hour must have 2 digits (e.g.: 1 -> 01)
        """
        # list of values from 00 to 23, append 0 if single digit
        hour_format = ["0"+str(i) if i < 10 else str(i) for i in range(0, 24)]
        if hour is None:
            hour = input(" Please set the alarm hour (xx) time: ")
        if hour not in hour_format:
            print("\n\tInvalid hour input (only 00 to 23 are acceptable)\n")
            return self._get_hour(None)
        return hour

    def _get_minute(self, minute):
        """minutes must have 2 digits (e.g.: 1 -> 01)"""
        # list of values from 00 to 59, append if single digit
        minute_format = ["0"+str(i) if i < 10 else str(i)
                         for i in range(0, 60)]
        if minute is None:
            minute = input(" Please set the alarm minute (xx) time: ")
        if minute not in minute_format:
            print("\n\tInvalid minute input (only 00 to 59 are acceptable)\n")
            return self._get_minute(None)
        return minute

    def get_dates(self, choice=None):
        """Set a day or days to turn alarm on"""
        if choice is None:
            choice = input("""\
     Which day or days do you want the alarm to be turned on?
     Monday    : 1
     Tuesday   : 2
     Wednesday : 3
     Thursday  : 4
     Friday    : 5
     Saturday  : 6
     Sunday    : 7
     > """)
        return self._get_dates(choice)

    def _get_dates(self, choice):
        """get dates main function"""
        date_dict = {
            "1": 1,
            "2": 2,
            "3": 3,
            "4": 4,
            "5": 5,
            "6": 6,
            "7": 7
        }
        date_choice = []
        for i in choice:
            if date_dict.get(i) is None:
                print("\n\tInvalid input\n")
                return self.get_dates(choice=None)
            date_choice.append(int(i))
        return date_choice

    @staticmethod
    def _initial_write(_dates="None", _time="None",
                       _ringtone="None", _volume="None"):
        """Create settings.txt and initialize inputs as None"""
        with open("settings.txt", "w") as ftxt:
            ftxt.write(_dates + "\n")
            ftxt.write(_time + "\n")
            ftxt.write(_ringtone + "\n")
            ftxt.write(_volume + "\n")

    @staticmethod
    def _overwrite(line_num, _data):
        """
        Overwrite saved settings in settings.txt
        for loop is used to rewrite each line in the settings.txt
        """
        with open("settings.txt", "r+") as ftxt:
            new_data = ftxt.read().split("\n")
            new_data[line_num] = _data
            ftxt.seek(0)
            for i in range(4):
                ftxt.write(new_data[i] + "\n")

    def _set_schedule(self):
        """Set, write, and save schedule settings to settings.txt file"""
        _dates = "".join([str(i) for i in self.get_dates()])
        if self.file_exist() is True:
            if self.file_is_empty() is False:
                self._overwrite(0, _dates)
                return self.settings()
        self._initial_write(_dates=_dates)
        return self.settings()

    def _set_time(self):
        """Set, write, and save alarm time setting to settings.txt file"""
        _time = self.get_alarm_time()
        if self.file_exist() is True:
            if self.file_is_empty() is False:
                self._overwrite(1, _time)
                return self.settings()
        self._initial_write(_time=_time)
        return self.settings()

    def _set_ringtone(self):
        """Set, write, and save ringtone setting to settings.txt file"""
        _path = input("""\
    Key in file path
    e.g.: 'alarm-volume-control/audio/sample.mp3'
    > """)
        if self.file_exist() is True:
            if self.file_is_empty() is False:
                self._overwrite(2, _path)
                return self.settings()
        self._initial_write(_ringtone=_path)
        return self.settings()

    def _set_volume(self):
        """Set, write, and save alarm volume setting to settings.txt file"""
        _vol = input("Alarm volume level: 0 to 100\n> ")
        if self.file_exist() is True:
            if self.file_is_empty() is False:
                self._overwrite(3, _vol)
                return self.settings()
        self._initial_write(_volume=_vol)
        return self.settings()

    def _view_settings(self):
        """
        View currently saved settings
        Currently, only 4 settings can be implemented
        therefore in the for loop, range is set to (4)
        to display all saved settings
        """
        if self.file_exist() is True:
            if self.file_is_empty() is False:
                for i in range(4):
                    self._read(i)
                return self.settings()
        print("\n\tNo settings saved\n")
        return self.settings()

    @staticmethod
    def _read(line_num):
        """Read settings.txt file"""
        with open("settings.txt", "r") as ftxt:
            lines = ftxt.readlines()
            ftxt.seek(0)
            for i, line in enumerate(lines):
                if i == line_num:
                    print(line, end="")

    @staticmethod
    def file_is_empty():
        """Check if text file is empty"""
        return os.stat("settings.txt").st_size == 0

    @staticmethod
    def file_exist():
        """Check if file exists"""
        return os.path.isfile("settings.txt")


# -*- coding: utf-8 -*-
# __author__ = 'gaohao'
# last_modify : 2019.10.14

import re,os,shutil
from biocluster.agent import Agent
from biocluster.tool import Tool
from biocluster.core.exceptions import OptionError
from mbio.packages.align.blast.xml2table import xml2table
from mbio.packages.bac_comp_genome.common_function import link_file

class CompareTreeAgent(Agent):
    """
    iqtree进行物种树和基因树的比较
    """

    def __init__(self, parent):
        super(CompareTreeAgent, self).__init__(parent)
        options = [
            {"name": "species_tree", "type": "infile", "format": "graph.newick_tree"},  # 物种树文件夹
            {"name": "gene_tree", "type": "infile", "format": "graph.newick_tree"}, #基因树文件夹
        ]
        self.add_option(options)

    def check_options(self):
        if not self.option("species_tree"):
            raise OptionError("必须输入species_tree文件！")
        if not self.option("gene_dir"):
            raise OptionError("必须输入gene_tree文件！")
        return True

    def set_resource(self):
        self._cpu = 2
        self._memory = '20G'

    def end(self):
        super(CompareTreeAgent, self).end()

class CompareTreeTool(Tool):
    def __init__(self, config):
        super(CompareTreeTool, self).__init__(config)
        self._version = "1.0"
        self.sof_path = self.config.SOFTWARE_DIR + "/bioinfo/compare_genome/software/iqtree-1.6.12-Linux/bin/iqtree"
        self.species = self.option("species_tree").prop['path']
        self.sh = "../../../../../.." + self.config.PACKAGE_DIR + "/bac_comp_genome/roary.sh"
        self.gene= self.option("gene_tree").prop['path']
        self.outfile = self.output_dir + "/compare_result.xls"

    def run(self):
        """
        运行
        :return:
        """
        super(CompareTreeTool, self).run()
        self.run_tree()
        self.set_output()
        self.end()

    def run_tree(self):
        cmd = '{} {} {} {} {}'.format(self.sh, self.sof_path, self.species, self.gene, self.outfile)
        command = self.add_command("run_tree", cmd).run()
        self.wait(command)
        if command.return_code == 0:
            self.logger.info("run_tree运行完成！")
        else:
            self.set_error("run_tree运行完成运行出错!")

    def set_output(self):
        pass


from torch.autograd import Variable as Vb
import torch.nn as nn
from utils.utils import *
from modules.layers.vgg import Vgg19
from torchvision import transforms as trn
from utils.ops import resample

preprocess = trn.Compose([
    trn.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

mean = Vb(torch.FloatTensor([0.485, 0.456, 0.406])).view([1, 3, 1, 1])
std = Vb(torch.FloatTensor([0.229, 0.224, 0.225])).view([1, 3, 1, 1])

def normalize(x):
    x = (x+1) / 2
    gpu_id = x.get_device()
    return (x - mean.cuda(gpu_id))/std.cuda(gpu_id)

class PerceptualLoss(nn.Module):
    def __init__(self, train_params):
        super(PerceptualLoss, self).__init__()
        self.vgg19 = Vgg19()
        self.train_params = train_params
        self.criterion = nn.L1Loss()

    @staticmethod
    def compute_gram(x):
        b, ch, h, w = x.size()
        f = x.view(b, ch, w * h)
        f_t = f.transpose(1, 2)
        g = f.bmm(f_t) / (h * w * ch)

        return g

    def forward(self, gt, fake):
        out_dict = {}
        content_loss = 0.0
        style_loss = 0.0
        weights = [1.0, 1.0, 1.0, 1.0, 1.0]
        for i in range(self.train_params["num_predicted_frames"]):
            gt_frame = gt[:, :, i, ...]
            fake_frame = fake[:, :, i, ...]
            x_vgg, y_vgg = self.vgg19(gt_frame), self.vgg19(fake_frame)

            if self.train_params["loss_weights"].get("style", 0) > 0:
                style_loss += \
                    self.criterion(self.compute_gram(x_vgg['relu2_2'].detach()), self.compute_gram(y_vgg['relu2_2']))
                style_loss += \
                    self.criterion(self.compute_gram(x_vgg['relu3_4'].detach()), self.compute_gram(y_vgg['relu3_4']))
                style_loss += \
                    self.criterion(self.compute_gram(x_vgg['relu4_4'].detach()), self.compute_gram(y_vgg['relu4_4']))
                style_loss += \
                    self.criterion(self.compute_gram(x_vgg['relu5_2'].detach()), self.compute_gram(y_vgg['relu5_2']))

            if self.train_params["loss_weights"].get("perceptual", 0) > 0:
                content_loss += weights[0] * self.criterion(x_vgg['relu1_1'].detach(), y_vgg['relu1_1'])
                content_loss += weights[1] * self.criterion(x_vgg['relu2_1'].detach(), y_vgg['relu2_1'])
                content_loss += weights[2] * self.criterion(x_vgg['relu3_1'].detach(), y_vgg['relu3_1'])
                content_loss += weights[3] * self.criterion(x_vgg['relu4_1'].detach(), y_vgg['relu4_1'])
                content_loss += weights[4] * self.criterion(x_vgg['relu5_1'].detach(), y_vgg['relu5_1'])
        if content_loss > 0:
            out_dict["perceptual"] = content_loss / self.train_params["num_predicted_frames"]
        if style_loss > 0:
            out_dict["style"] = style_loss / self.train_params["num_predicted_frames"]
        return out_dict

class SmoothLoss(nn.Module):
    def __init__(self):
        super(SmoothLoss, self).__init__()

    @staticmethod
    def gradient_x(img):
        gx = (img[:, :, :-1, :] - img[:, :, 1:, :])
        return gx

    @staticmethod
    def gradient_y(img):
        gy = (img[:, :, :, :-1] - img[:, :, :, 1:])
        return gy

    def compute_smooth_loss(self, flow_x, img):
        flow_gradients_x = self.gradient_x(flow_x)
        flow_gradients_y = self.gradient_y(flow_x)

        image_gradients_x = self.gradient_x(img)
        image_gradients_y = self.gradient_y(img)

        weights_x = torch.exp(-torch.mean(torch.abs(image_gradients_x), 1, True))
        weights_y = torch.exp(-torch.mean(torch.abs(image_gradients_y), 1, True))

        smoothness_x = flow_gradients_x * weights_x
        smoothness_y = flow_gradients_y * weights_y

        return torch.mean(torch.abs(smoothness_x)) + torch.mean(torch.abs(smoothness_y))

    def compute_flow_smooth_loss(self, flow, img):
        smoothness = 0
        _, c, h, w = flow.size()
        # flow = torch.cat([flow[:, 0:1, :, :] * ((w - 1.0) / 2.0), flow[:, 1:2, :, :] * ((h - 1.0) / 2.0)], dim=1)
        for i in range(2):
            smoothness += self.compute_smooth_loss(flow[:, i:i+1, :, :], img)
        return smoothness/2

    def forward(self, flow, image):
        return self.compute_flow_smooth_loss(torch.cat(torch.unbind(flow, dim=2), dim=0),
                                             torch.cat(torch.unbind(image, dim=2), dim=0))

class FlowConsistLoss(nn.Module):

    def __init__(self, train_params):
        super(FlowConsistLoss, self).__init__()
        self.train_params = train_params

    @staticmethod
    def _flowconsist(flow, flowback, mask_fw=None, mask_bw=None):
        if mask_fw is not None:
            nextloss = (mask_fw * torch.abs(resample(flowback, flow) + flow)).mean()
            prevloss = (mask_bw * torch.abs(resample(flow, flowback) + flowback)).mean()
        else:
            nextloss = torch.abs(resample(flowback, flow) + flow).mean()
            prevloss = torch.abs(resample(flow, flowback) + flowback).mean()
        return prevloss + nextloss

    def forward(self, flow, flowback, mask_fw=None, mask_bw=None):
        if mask_bw is not None:
            flowcon = self._flowconsist(torch.cat(torch.unbind(flow, dim=2), dim=0),
                                        torch.cat(torch.unbind(flowback, dim=2), dim=0),
                                        mask_fw=torch.cat(torch.unbind(mask_fw, dim=2), dim=0),
                                        mask_bw=torch.cat(torch.unbind(mask_bw, dim=2), dim=0))
        else:
            flowcon = self._flowconsist(torch.cat(torch.unbind(flow, dim=2), dim=0),
                                        torch.cat(torch.unbind(flowback, dim=2), dim=0))
        return flowcon * self.train_params["num_predicted_frames"]

class KLLoss(nn.Module):
    def __init__(self):
        super(KLLoss, self).__init__()

    def forward(self, mu, logvar):
        KLD = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())
        return KLD / mu.numel()

class SSIMLoss(nn.Module):
    def __init__(self):
        super(SSIMLoss, self).__init__()

    @staticmethod
    def ssim(x, y):
        c1 = 0.01 ** 2
        c2 = 0.03 ** 2

        mu_x = F.avg_pool2d(x, 3, 1)
        mu_y = F.avg_pool2d(y, 3, 1)

        sigma_x = F.avg_pool2d(x ** 2, 3, 1) - mu_x ** 2
        sigma_y = F.avg_pool2d(y ** 2, 3, 1) - mu_y ** 2
        sigma_xy = F.avg_pool2d(x * y, 3, 1) - mu_x * mu_y

        ssim_n = (2 * mu_x * mu_y + c1) * (2 * sigma_xy + c2)
        ssim_d = (mu_x ** 2 + mu_y ** 2 + c1) * (sigma_x + sigma_y + c2)

        ssim = ssim_n / ssim_d

        return torch.clamp((1 - ssim) / 2, 0, 1).mean()

    def forward(self, x, y):
        sim = self.ssim(torch.cat(torch.unbind(x, dim=2), dim=0), torch.cat(torch.unbind(y, dim=2), dim=0))
        return sim

class L1MaskedLoss(nn.Module):
    def __init__(self):
        super(L1MaskedLoss, self).__init__()

    def forward(self, source, target, mask=None):
        if mask is not None:
            mask = mask.expand_as(source)
            return F.l1_loss(source * mask, target * mask)
        else:
            return F.l1_loss(source, target)

class TrainingLosses(nn.Module):
    def __init__(self, train_params, model_params):
        super(TrainingLosses, self).__init__()
        self.train_params = train_params
        self.model_params = model_params
        if self.train_params["loss_weights"]["perceptual"] > 0:
            self.perceptual_loss = PerceptualLoss(train_params)
        self.flow_consist = FlowConsistLoss(self.train_params)
        self.smooth_loss = SmoothLoss()
        self.kl_loss = KLLoss()
        self.ssim_loss = SSIMLoss()
        self.l1_masked_loss = L1MaskedLoss()

    def forward(self, data, frames, bw_optical_flows, fw_optical_flows, bw_occlusion_masks, fw_occlusion_masks,
                generated, tracking_gnn):
        loss_dict = {}
        source_frame = frames[:, :, self.train_params["num_input_frames"] - 1, ...]
        target_frames = frames[:, :, self.train_params["num_input_frames"]:, ...]
        '''flowloss'''

        loss_dict["flow_reconstruction"] = self.l1_masked_loss(generated["dense_motion_bw"], bw_optical_flows,
                                                               bw_occlusion_masks)
        if fw_optical_flows is not None:
            loss_dict["flow_reconstruction"] += self.l1_masked_loss(generated["dense_motion_fw"],
                                                                    fw_optical_flows, fw_occlusion_masks)
            loss_dict["flowcon"] = self.flow_consist(generated["dense_motion_fw"], generated["dense_motion_bw"],
                                                     generated["occlusion_fw"], generated["occlusion_bw"])
        warped_frames = torch.cat([torch.unsqueeze(resample(source_frame,
                                                            generated["dense_motion_bw"][:, :, i, ...]),
                                                   2) for i in range(self.train_params["num_predicted_frames"])], 2)
        loss_dict["warped"] = self.l1_masked_loss(warped_frames, target_frames)
        if self.train_params["loss_weights"]["flow_smooth"] > 0:
            loss_dict["flow_smooth"] = self.smooth_loss(generated["dense_motion_bw"], target_frames)
            if fw_optical_flows is not None:
                loss_dict["flow_smooth"] += self.smooth_loss(generated["dense_motion_fw"],
                                                   torch.unsqueeze(source_frame, 2).repeat(1, 1, target_frames.shape[2],
                                                                                1, 1))
        '''kldloss'''
        loss_dict["kl"] = self.kl_loss(generated["mu"], generated["logvar"])
        '''Image Similarity loss'''
        loss_dict["ssim"] = self.ssim_loss(generated["generated"], target_frames)
        loss_dict["reconstruction"] = self.l1_masked_loss(generated["generated"], target_frames)
        '''vgg loss'''
        loss_dict.update(self.perceptual_loss(target_frames,
                                              generated["generated"]))
        '''mask loss'''
        loss_dict["occlusion_bw"] = self.l1_masked_loss(bw_occlusion_masks, generated["occlusion_bw"])
        if fw_optical_flows is not None:
            loss_dict["occlusion_fw"] = self.l1_masked_loss(fw_occlusion_masks, generated["occlusion_fw"])
        scale = 0
        rotation = 0
        translation = 0
        for t in range(self.train_params["num_predicted_frames"]):
            translation += self.l1_masked_loss(generated[f"theta_{t}"][:, 2], tracking_gnn.targets_theta[:, t][:, 2])
            translation += self.l1_masked_loss(generated[f"theta_{t}"][:, 5], tracking_gnn.targets_theta[:, t][:, 5])
            scale += self.l1_masked_loss(generated[f"theta_{t}"][:, 0], tracking_gnn.targets_theta[:, t][:, 0])
            scale += self.l1_masked_loss(generated[f"theta_{t}"][:, 4], tracking_gnn.targets_theta[:, t][:, 4])
            rotation += self.l1_masked_loss(generated[f"theta_{t}"][:, 1], tracking_gnn.targets_theta[:, t][:, 1])
            rotation += self.l1_masked_loss(generated[f"theta_{t}"][:, 3], tracking_gnn.targets_theta[:, t][:, 3])
        loss_dict["translation"] = loss_dict.get("translation", 0) + isnan(translation)
        loss_dict["scale"] = loss_dict.get("scale", 0) + isnan(scale)
        loss_dict["rotation"] = loss_dict.get("rotation", 0) + isnan(rotation)

        return loss_dict


import tkinter
import math
import random

N = 8
GRID = 40
BLOB = GRID>>2
XMAX = 2*GRID+int(N*math.log2(N)*(math.log2(N)-1)/4+N-1)*GRID
YMAX = GRID+N*GRID
NODES= []

# Main window
def create_window():
    window = tkinter.Tk()
    window.title('Pairwise')
    window.geometry('{}x{}'.format(XMAX, YMAX))
    return window

# Create canvas and add to main window
def create_canvas(window):
    canvas = tkinter.Canvas(window)
    canvas.configure(bg=darkgray)
    canvas.pack(fill='both', expand=True)
    x = GRID>>1
    for y in range(0, N):
        canvas.create_line(0, GRID+GRID*y, XMAX, GRID+GRID*y, width=4, fill=pastelorange)
        canvas.create_oval(x-BLOB, GRID+GRID*y-BLOB, x+BLOB, GRID+GRID*y+BLOB, width=BLOB, outline=pastelorange, fill=pastelorange)
        canvas.create_oval(XMAX-2*BLOB, GRID+GRID*y-BLOB, XMAX, GRID+GRID*y+BLOB, width=BLOB, outline=pastelorange, fill=pastelorange)
    return canvas

def pairwise(window, canvas, data):
    x = GRID>>1
    for y in range(0, N):
        canvas.create_text(x, GRID+GRID*y, text=data[y])
    col = 0
    x = GRID + (GRID>>1)

    # Create the lexicographically sorted pair set
    a = 1
    while a < N:
        b = a
        c = 0
        while b < N:
            NODES.append(b-a)
            NODES.append(b)
            canvas.create_line(x, GRID+GRID*(b-a), x, GRID+GRID*b, width=BLOB, fill=COLOR[col])
            canvas.create_oval(x-BLOB, GRID+GRID*(b-a)-BLOB, x+BLOB, GRID+GRID*(b-a)+BLOB, width=BLOB, outline=COLOR[col], fill=COLOR[col])
            canvas.create_oval(x-BLOB, GRID+GRID*b-BLOB, x+BLOB, GRID+GRID*b+BLOB, width=BLOB, outline=COLOR[col], fill=COLOR[col])
            if data[b-a] > data[b]:
                data[b-a], data[b] = data[b], data[b-a]
                canvas.create_text(x, GRID+GRID*(b-a), text=data[b-a])
                canvas.create_text(x, GRID+GRID*b, text=data[b])
            x = x + GRID
            b = b + 1
            c = c + 1
            if c >= a:
                c = 0
                b = b + a
        a = a << 1
        col = col + 1

    # Begin the pairwise sort
    a = N >> 2
    e = 1
    while a > 0:
        d = e
        while d > 0:
            b = (d + 1) * a
            c = 0
            while b < N:
                NODES.append(b-d*a)
                NODES.append(b)
                canvas.create_line(x, GRID+GRID*(b-d*a), x, GRID+GRID*b, width=BLOB, fill=COLOR[col])
                canvas.create_oval(x-BLOB, GRID+GRID*(b-d*a)-BLOB, x+BLOB, GRID+GRID*(b-d*a)+BLOB, width=BLOB, outline=COLOR[col], fill=COLOR[col])
                canvas.create_oval(x-BLOB, GRID+GRID*b-BLOB, x+BLOB, GRID+GRID*b+BLOB, width=BLOB, outline=COLOR[col], fill=COLOR[col])
                if data[b-d*a] > data[b]:
                    data[b-d*a], data[b] = data[b], data[b-d*a]
                    canvas.create_text(x, GRID+GRID*(b-d*a), text=data[b-d*a])
                    canvas.create_text(x, GRID+GRID*b, text=data[b])
                x = x + GRID
                b = b + 1
                c = c + 1
                if c >= a:
                    c = 0
                    b = b + a
            d = d >> 1
        a = a >> 1
        col = col + 1
        e = 2*e + 1;
    for y in range(0, N):
        canvas.create_text(XMAX-BLOB, GRID+GRID*y, text=data[y])

    window.update()
    return data

# Main
with open('lm_bolokai.py') as f: exec(f.read())
COLOR = [pastelblue, pastelyellow, pastelpurple, pastelgreen, pastelpink,
        darkred, darkgreen, darkblue, brightgreen, darkmagenta, darkwhite, black]

window = create_window()
canvas = create_canvas(window)

data = list(range(0, N))
random.shuffle(data)
print(data)
data = pairwise(window, canvas, data)
print(data)
print("CX: ",int(N*math.log2(N)*(math.log2(N)-1)/4+N-1))
print("n.log(n): ", int(N*math.log2(N)))
print("Nodes: ", NODES)
i=input('ENTER TO CLOSE')
window.destroy()


#importing library
from sklearn import svm, datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#from mlxtend.plotting import plot_decision_regions

#import dataset
df = pd.read_csv("Iris.csv")
df.head()

#divide dataset into: train, test, X, Y
y = df[['Species']]
X = df[['SepalLengthCm', 'SepalWidthCm']]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

print(X_train.shape, y_train.shape)
print(X_test.shape, y_test.shape)

#creating svm classification object
model_lin = svm.SVC(kernel='linear', C=1, gamma=1)

model_rbf_c1 = svm.SVC(kernel='rbf', C=1, gamma=1)
model_rbf_c2 = svm.SVC(kernel='rbf', C=10, gamma=1)
model_rbf_c3 = svm.SVC(kernel='rbf', C=100, gamma=1)

model_rbf_g1 = svm.SVC(kernel='rbf', C=1, gamma=0.5)
model_rbf_g2 = svm.SVC(kernel='rbf', C=1, gamma=1)
model_rbf_g3 = svm.SVC(kernel='rbf', C=1, gamma=10)

#training model using training set
model_lin.fit(X_train, y_train)

model_rbf_c1.fit(X_train, y_train)
model_rbf_c2.fit(X_train, y_train)
model_rbf_c3.fit(X_train, y_train)

model_rbf_g1.fit(X_train, y_train)
model_rbf_g2.fit(X_train, y_train)
model_rbf_g3.fit(X_train, y_train)

#checking score
model_lin.score(X_train, y_train)

model_rbf_c1.score(X_train, y_train)
model_rbf_c2.score(X_train, y_train)
model_rbf_c3.score(X_train, y_train)

model_rbf_g1.score(X_train, y_train)
model_rbf_g2.score(X_train, y_train)
model_rbf_g3.score(X_train, y_train)

#predict output
y_pred_lin = model_lin.predict(X_test)

y_pred_rbf_c1 = model_rbf_c1.predict(X_test)
y_pred_rbf_c2 = model_rbf_c2.predict(X_test)
y_pred_rbf_c3 = model_rbf_c3.predict(X_test)

y_pred_rbf_g1 = model_rbf_g1.predict(X_test)
y_pred_rbf_g2 = model_rbf_g2.predict(X_test)
y_pred_rbf_g3 = model_rbf_g3.predict(X_test)

#printing accuracy
print('The linear accuracy is: ', accuracy_score(y_pred_lin, y_test))
print(confusion_matrix(y_test, y_pred_lin))
print(classification_report(y_test, y_pred_lin))

print('\nThe RBF (C=1, G=1) accuracy is: ', accuracy_score(y_pred_rbf_c1, y_test))
print(confusion_matrix(y_test, y_pred_rbf_c1))
print(classification_report(y_test, y_pred_rbf_c1))

print('\nThe RBF (C=10, G=1) accuracy is: ', accuracy_score(y_pred_rbf_c2, y_test))
print('The RBF (C=100, G=1) accuracy is: ', accuracy_score(y_pred_rbf_c3, y_test))

print('\nThe RBF (C=1, G=0.5) accuracy is: ', accuracy_score(y_pred_rbf_g1, y_test))
print('The RBF (C=1, G=1) accuracy is: ', accuracy_score(y_pred_rbf_g2, y_test))
print('The RBF (C=1, G=10) accuracy is: ', accuracy_score(y_pred_rbf_g3, y_test))

def make_meshgrid(x, y, h=.02):
    """Create a mesh of points to plot in

    Parameters
    ----------
    x: data to base x-axis meshgrid on
    y: data to base y-axis meshgrid on
    h: stepsize for meshgrid, optional

    Returns
    -------
    xx, yy : ndarray
    """
    x_min, x_max = x.min() - 1, x.max() + 1
    y_min, y_max = y.min() - 1, y.max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))
    return xx, yy

def plot_contours(ax, clf, xx, yy, **params):
    """Plot the decision boundaries for a classifier.

    Parameters
    ----------
    ax: matplotlib axes object
    clf: a classifier
    xx: meshgrid ndarray
    yy: meshgrid ndarray
    params: dictionary of params to pass to contourf, optional
    """
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    out = ax.contourf(xx, yy, Z, **params)
    return out

# import some data to play with
iris = datasets.load_iris()
# Take the first two features. We could avoid this by using a two-dim dataset
X = iris.data[:, :2]
y = iris.target

# we create an instance of SVM and fit out data. We do not scale our
# data since we want to plot the support vectors
C = 1.0  # SVM regularization parameter
models = (svm.SVC(kernel='linear', C=C),
          svm.LinearSVC(C=C),
          svm.SVC(kernel='rbf', gamma=0.7, C=C),
          svm.SVC(kernel='poly', degree=3, C=C))
models = (clf.fit(X, y) for clf in models)

# title for the plots
titles = ('SVC with linear kernel',
          'LinearSVC (linear kernel)',
          'SVC with RBF kernel',
          'SVC with polynomial (degree 3) kernel')

# Set-up 2x2 grid for plotting.
fig, sub = plt.subplots(2, 2)
plt.subplots_adjust(wspace=0.4, hspace=0.4)

X0, X1 = X[:, 0], X[:, 1]
xx, yy = make_meshgrid(X0, X1)

for clf, title, ax in zip(models, titles, sub.flatten()):
    plot_contours(ax, clf, xx, yy,
                  cmap=plt.cm.coolwarm, alpha=0.8)
    ax.scatter(X0, X1, c=y, cmap=plt.cm.coolwarm, s=20, edgecolors='k')
    ax.set_xlim(xx.min(), xx.max())
    ax.set_ylim(yy.min(), yy.max())
    ax.set_xlabel('Sepal length')
    ax.set_ylabel('Sepal width')
    ax.set_xticks(())
    ax.set_yticks(())
    ax.set_title(title)

plt.show()


#!/usr/bin/env python3
"""
Function named index_range that takes two integer
arguments page and page_size and returns a tuple
of size two containing a start index and an end
index corresponding to the range of indexes to
return in a list for those particular pagination
parameters
"""
from typing import Tuple

def index_range(page: int, page_size: int) -> Tuple[int, int]:
    """
    Function that returns a tuple containing a start
    index and an end index
    """
    upper_limit = (page * page_size) - page_size
    lower_limit = page * page_size
    indexes_range = (upper_limit, lower_limit)
    return indexes_range


import sys
sys.path.append('src')

from matrix import Matrix
import math
import random

A = Matrix([[4, 3], [2, 1]])
B = Matrix([[4, 3], [2, 1]])
Identity = Matrix([[1, 0], [0, 1]])
A_and_identity = Matrix([[5, 3], [2, 2]])
At = Matrix([[4, 2], [3, 1]])
Ad = Matrix([[1, 1], [-1, -1]])
double_identity = Matrix([[2, 0], [0, 2]])
Three_Identity = Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
AB = Matrix(([1, 1, 0], [2, -1, 0], [0, 0, 3]))
AB_cubed = Matrix(([3, 3, 0], [6,  -3, 0], [0, 0, 27]))
AB_squared = AB ** 2

assert At == A.transpose()
assert A + Identity == A_and_identity
assert A_and_identity - Identity == A
assert Identity * 2 == double_identity
assert AB ** 3 == AB_cubed
assert AB_squared @ AB == AB_cubed

C = Matrix([[4, 7], [0, -3], [9, 1]])
D = Matrix([[1, 2, -1], [1, 0, 1]])
Ay = Matrix([[7, -1, 11, 0], [8, -2, 3, 1], [-5, 4, -2, 6], [0, 5, -8, -9]])
X = Matrix([[3, 0, 0, 2], [8, 0, 3, 9], [2, 0, 2, 2], [1, 0, 1, 1]])
Three = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 0]])

if Ay.recursive_determinant_calc() != -4352:
    print("recursive_determinant_calc is broken")
if B.recursive_determinant_calc() != -2:
    print("recursive_determinant_calc is broken")
"""
print("The row reduced echelon form of")
D.print()
print("is:")
D.rref().print()
print()
print("The row reduced echelon form of")
Ay.print()
print("is:")
Ay.rref().print()
print()
print("The row reduced echelon form of")
C.print()
print("is:")
C.rref().print()
print()
print("The row reduced echelon form of")
X.print()
print("is:")
X.rref().print()
"""
"""
print("The inverse of the matrix")
A.print()
print("is: ")
A.inverse().print()
print()
print("The inverse of the matrix")
At.print()
print("is: ")
At.inverse().print()
print()
print("The inverse of the matrix")
A_and_identity.print()
print("is: ")
A_and_identity.inverse().print()
print()
print("The inverse of the matrix")
Three.print()
print("is: ")
Three.inverse().print()
"""
if Ay.recursive_determinant_calc() != Ay.determinant():
    print("broken 1")
if A.recursive_determinant_calc() != A.determinant():
    print("broken 2")
if X.recursive_determinant_calc() != X.determinant():
    print("broken 3")


"""
This file and its tests are individualized for NetID mkannaia.
"""
import torch as tr
import numpy as np
from Play_blackjack import deck_lookup, BlackJack, log
from BlackJackState import State, decision

def uniform(node):
    c = np.random.choice(len(node.children()))
    return node.children()[c]

def puct(node):
    c = np.random.choice(len(node.children()), p=puct_probs(node))
    return node.children()[c]

def puct_probs(node):
    probs = []
    n = node.get_visit_counts()
    q = node.get_score_estimates()
    probs  = np.exp(q + np.power(np.divide(np.log(node.visit_count+1),n+1),0.5))
    return(np.divide(probs,sum(probs)))
    #raise(NotImplementedError)

class Node(object):
    def __init__(self, state, depth = 0, choose_method=uniform):
        self.state = state
        self.child_list = None
        self.visit_count = 0
        self.score_total = 0
        self.depth = depth
        self.visited = False
        self.choose_method = choose_method

    def make_child_list(self):
        self.child_list = []
        actions = self.state.validAction()
        #print(self.state)
        #print(actions)
        for i in actions:
            if(self.state.turn == 2):
                deck = deck_lookup.flatten().tolist()
                rmv_list = np.append(self.state.state.player.cards,self.state.state.dealer.cards).tolist()
                deck = [i for i in deck if i not in rmv_list]
                for j in deck:
                    child_state = self.state.PerformAction(action = i, card = j)
                    #print(child_state)
                    child_node = Node(state= child_state, depth=self.depth+1, choose_method= self.choose_method)
                    self.child_list.append(child_node)
            else:
                child_state = self.state.PerformAction(i)
                child_node = Node(state= child_state, depth=self.depth+1, choose_method= self.choose_method)
                self.child_list.append(child_node)

    def children(self):
        #print("Enters here")
        if self.child_list is None: self.make_child_list()
        return self.child_list

    def get_score_estimates(self):
        Q = []
        for i in self.child_list:
            if(i.visit_count == 0):
                Q.append(0)
            else:
                Q.append(i.score_total/i.visit_count)
        return np.array(Q)

    def get_visit_counts(self):
        N=[]
        for i in self.child_list:
            N.append(i.visit_count)
        return np.array(N)

    def choose_child(self):
        return self.choose_method(self)

def rollout(node, max_depth=None):
    if node.depth == max_depth or node.state.isLeaf:
        result = node.state.state.score
    else:
        result = rollout(node.choose_child(), max_depth)
    node.visit_count += 1
    node.score_total += result
    node.visited = True
    return result

def processedNodes(node, max_depth):
    result = 0
    if node.depth == max_depth or node.state.isLeaf:
        if node.visited: return 1
        else: return 0
    elif node.child_list is not None:
        for i in node.child_list:
            result += processedNodes(i, node.depth)
    else:
        return 0
    return result+1 # +1 for Root node

def decide_action(state, num_rollouts, choose_method=puct, max_depth=None, verbose=False):
    node = Node(state, choose_method=choose_method)
    for n in range(num_rollouts):
        if verbose and n % 100 == 0: print("Rollout %d of %d..." % (n+1, num_rollouts))
        rollout(node, max_depth=max_depth)
    #print(node.get_score_estimates())
    return np.argmax(node.get_score_estimates()), node, processedNodes(node,max_depth)

if __name__ == "__main__":
    #Problem size
    while True:
        try:
            gameSize = int(input("Enter the number of decks:"))
            break
        except ValueError:
            print("Invalid input. Please enter an integer")
    while True:
        a = input("\nEnter an action: P: PLAY, Q:QUIT - ")
        if(a == "p" or a == "P"):
            bj = BlackJack(gameSize)
            bj.beginGame()
            bj.playerTurn()
            state = State(game = bj)
            node = Node(state = state)
            AI = ""
            #net = BlackjackNet1(gameSize)
            #net.load_state_dict(tr.load("model%d.pth" % gameSize))
            #Choice of AI
            while bj.log == log.Unfinished_Game:
                AI = input("Choose an AI: B: Baseline AI, T: Tree-based - ")
                if(AI == "T" or AI == "t" or AI == "B" or AI == "b"or AI == "N"or AI == "n"): break
                print("Please enter a valid input")

            while(bj.log == log.Unfinished_Game):
                #Baseline AI
                if(AI == "B" or AI == "b"):
                    bj.dealerTurn()
                    bj.compare()
                    #print(bj.gameStatus.name)
                    break
                #Tree-Based
                elif(AI == "T" or AI == "t"):
                    # Stop when game is over
                    if node.state.isLeaf:
                        break
                    a, n, nump = decide_action(node.state,choose_method=puct, num_rollouts=1000, max_depth = 10, verbose=True)
                    state = n.children()[a].state
                    print("\nNumber of Processed nodes: ",nump)
                    if(state.childAction == decision.PositiveHit):
                        bj.hit(member = bj.dealer,sign="+")
                    elif(state.childAction == decision.NegativeHit):
                        bj.hit(member = bj.dealer,sign="-")
                    else:
                        bj.stand()
                        print(bj)
                        break
                    state = State(game = bj)
                    node = Node(state = state)
                    print(bj)
                    continue
                """
                else:
                    if node.state.isLeaf:
                        break
                    a, n, nump = decide_action(node.state,choose_method=nn_puct, num_rollouts=1000, max_depth = 10, verbose=True)
                    state = n.children()[a].state
                    print("\nNumber of Processed nodes: ",nump)
                    if(state.childAction == decision.PositiveHit):
                        bj.hit(member = bj.dealer,sign="+")
                    elif(state.childAction == decision.NegativeHit):
                        bj.hit(member = bj.dealer,sign="-")
                    else:
                        bj.stand()
                        print(bj)
                        break
                    state = State(game = bj)
                    node = Node(state = state)
                    print(bj)
                    continue
                """
            print(bj.gameStatus.name)
        elif(a == 'q' or a=="Q"):
            break
        else:
            print("Invalid Choice. Please try again")
    #print(bj.log.value)


from question_model import Question
from data import question_data
from quiz_brain import QuizBrain

question_bank = list()

for item in question_data:
    q_text = item["text"]
    q_answer = item["answer"]
    new_q = Question(q_text, q_answer)
    question_bank.append(new_q)

quiz = QuizBrain(question_bank)

while quiz.has_questions():
    quiz.next_question()
quiz.quiz_complete()


import sys

from cv2 import cv2

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("set file name")
        sys.exit(1)
    name = sys.argv[1]
    img = cv2.imread(name)
    cv2.imshow('my_image', img)
    cv2.waitKey(5000)
    cv2.destroyAllWindows()


"""Runs commands to produce convolved predicted counts map in current directory."""
import numpy as np
from astropy.coordinates import Angle
from astropy.units import Quantity
from astropy.io import fits
from astropy.wcs import WCS
from gammapy.cube import SkyCube, compute_npred_cube
from gammapy.datasets import FermiVelaRegion
from gammapy.irf import EnergyDependentTablePSF
from gammapy.utils.energy import EnergyBounds

__all__ = ['prepare_images']

def prepare_images():
    # Read in data
    fermi_vela = FermiVelaRegion()
    background_file = FermiVelaRegion.filenames()['diffuse_model']
    exposure_file = FermiVelaRegion.filenames()['exposure_cube']
    counts_file = FermiVelaRegion.filenames()['counts_cube']
    background_model = SkyCube.read(background_file, format='fermi-background')
    exposure_cube = SkyCube.read(exposure_file, format='fermi-exposure')

    # Re-project background cube
    repro_bg_cube = background_model.reproject(exposure_cube)

    # Define energy band required for output
    energies = EnergyBounds([10, 500], 'GeV')

    # Compute the predicted counts cube
    npred_cube = compute_npred_cube(repro_bg_cube, exposure_cube, energies,
                                    integral_resolution=5)

    # Convolve with Energy-dependent Fermi LAT PSF
    psf = EnergyDependentTablePSF.read(FermiVelaRegion.filenames()['psf'])
    kernels = psf.kernels(npred_cube)
    convolved_npred_cube = npred_cube.convolve(kernels, mode='reflect')

    # Counts data
    counts_cube = SkyCube.read(counts_file, format='fermi-counts')
    counts_cube = counts_cube.reproject(npred_cube)

    counts = counts_cube.data[0]
    model = convolved_npred_cube.data[0]

    # Load Fermi tools gtmodel background-only result
    gtmodel = fits.open(FermiVelaRegion.filenames()['background_image'])[0].data.astype(float)

    # Ratio for the two background images
    ratio = np.nan_to_num(model / gtmodel)

    # Header is required for plotting, so returned here
    wcs = npred_cube.wcs
    header = wcs.to_header()
    return model, gtmodel, ratio, counts, header


# coding=utf-8
"""
循环队列,会有一个空间是空闲的
"""
class CircularQueue(object):
    """循环队列"""
    def __init__(self,size):
        self.size  = size
        self.head = 0
        self.tail = 0
        self.array = []

    def enqueue(self,item):
        """入栈,入之前判断是否满"""
        if (self.tail+1)%self.size == self.head:
            return False
        self.array.insert(self.tail,item)
        self.tail = (self.tail+1)%self.size
        return True

    def dequeue(self):
        """出栈，出之前判断是否为空"""
        if self.tail == self.head:
            return
        temp = self.array[self.head]
        self.head = (self.head+1)%self.size
        return temp


from flask import Blueprint, render_template, redirect, url_for, request, jsonify
from flask_login import login_required, current_user
from datetime import datetime
from src import db
from src.models import User, Tweet, Like, Comment
from src.tweets.forms import CreateTweetForm, CreateCommentForm
import markdown2
import bleach

tweets = Blueprint('tweets', __name__)

@tweets.route("/tweet/create", methods=['GET', 'POST'])
@login_required
def tweet_create():
    form = CreateTweetForm()
    if form.validate_on_submit():
        time = datetime.utcnow()
        markdown = markdown2.markdown(form.textbody.data)
        bleached_markdown = bleach.clean(markdown, tags=['b', 'i', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'abbr', 'acronym', 'p', 'code', 'blockquote', 'table', 'tr', 'td', 'br', 'ol', 'li', 'pre', 'div', 'span', 'em', 'strong', 'cite', 'col', 'colgroup', 'datalist', 'dd', 'dt', 'dl', 'q', 's', 'small', 'sub', 'sup', 'td', 'tbody', 'th', 'thead', 'u'])
        tweet = Tweet(identifier=Tweet.get_identifier(), textbody_source=form.textbody.data, textbody_markdown=bleached_markdown, author=current_user, created_utc=time, is_nsfw=form.is_nsfw.data)
        db.session.add(tweet)
        db.session.commit()
        return redirect(url_for('main.home'))
    return render_template('tweets/tweet_create.html', title='Create a tweet', form=form)

@tweets.route("/tweet/<string:ident>")
@login_required
def tweet_show(ident):
    tweet = Tweet.query.filter_by(identifier=ident).first_or_404()
    comments = tweet.comments.filter(Comment.parent == None).all()
    return render_template('tweets/tweet.html', tweet=tweet, comments=comments, showCreateComment=True)

@tweets.route("/tweet/<string:ident>/edit", methods=['GET', 'POST'])
@login_required
def tweet_edit(ident):
    tweet = Tweet.query.filter_by(identifier=ident).first_or_404()
    if current_user.id != tweet.userid:
        abort(403)
    form = CreateTweetForm()
    if form.validate_on_submit():
        tweet.textbody_source = form.textbody.data
        tweet.textbody_markdown = markdown2.markdown(form.textbody.data)
        edited_time = datetime.utcnow()
        tweet.edited_utc = edited_time
        tweet.is_edited = True
        tweet.is_nsfw = form.is_nsfw.data
        db.session.commit()
        return redirect(url_for('main.home'))
    elif request.method == 'GET':
        form.textbody.data = tweet.textbody_source
        form.is_nsfw.data = tweet.is_nsfw
    return render_template('tweets/tweet_create.html', form=form, is_editing=True)

@tweets.route("/tweet/like", methods=['POST'])
def tweet_like():
    if not current_user.is_authenticated:
        response = {"statuscode": -1, "status": "Permission denied"}
        return jsonify(response)

    tweet_ident = request.json['ident']
    tweet = Tweet.query.filter_by(identifier=tweet_ident).first()
    if not tweet:
        response = {"statuscode": -1, "status": "Tweet not found"}
    else:
        if current_user.has_liked_tweet(tweet):
            current_user.unlike_tweet(tweet)
            response = {"statuscode": 0, "status": "Liked"}
        else:
            current_user.like_tweet(tweet)
            response = {"statuscode": 0, "status": "Unliked"}
        db.session.commit()
    return jsonify(response)

@tweets.route("/tweet/sticky", methods=['POST'])
@login_required
def tweet_sticky():
    if not current_user.is_authenticated:
        response = {"statuscode": -1, "status": "Permission denied"}
        return jsonify(response)

    tweet_ident = request.json['ident']
    tweet = Tweet.query.filter_by(identifier=tweet_ident).first()
    if tweet.userid == current_user.id:
        tweet.stickied = not tweet.stickied
        db.session.commit()
        response = {"statuscode": 0}
        return jsonify(response)
    else:
        response = {"statuscode": -1, "status": "Cannot sticky/unsticky the tweet"}
        return jsonify(response)
    response = {"statuscode": -1}
    return jsonify(response)

@tweets.route("/tweet/<string:ident>/comment/create", methods=['GET', 'POST'])
@login_required
def comment_create(ident):
    form = CreateCommentForm()
    tweet = Tweet.query.filter_by(identifier=ident).first_or_404()
    if form.validate_on_submit():
        comment = Comment(textbody=form.textbody.data, identifier=Comment.get_identifier(), tweet=tweet, author=current_user, recipient=tweet.author)
        comment.save()
        tweet.author.add_notification('unread_notifs_count', tweet.author.new_notifs())
        db.session.commit()
        return redirect(url_for('tweets.tweet_show', ident=ident))
    return render_template('tweets/comment_create.html', form=form)

@tweets.route("/comment/<string:ident>/replies", methods=['GET'])
@login_required
def comment_replies(ident):
    comment = Comment.query.filter_by(identifier=ident).first_or_404()
    return render_template('tweets/replies.html', comment=comment)

@tweets.route("/comment/<string:ident>/reply", methods=['GET', 'POST'])
@login_required
def comment_reply(ident):
    form = CreateCommentForm()
    p_comment = Comment.query.filter_by(identifier=ident).first_or_404()
    if form.validate_on_submit():
        comment = Comment(textbody=form.textbody.data, identifier=Comment.get_identifier(), tweet=p_comment.tweet, author=current_user, recipient=p_comment.tweet.author, parent=p_comment)
        comment.save()
        p_comment.author.add_notification('unread_notifs_count', p_comment.author.new_notifs())
        db.session.commit()
        return redirect(url_for('tweets.comment_replies', ident=p_comment.identifier))
    return render_template('tweets/comment_create.html', form=form, is_reply=True)


import numpy as np
from scipy import ndimage
def sobelImageSet(images):
    # Apply Sobel Filter in x- and y-direction.
    # Return combined sobelFilter
    sobX = np.zeros(images.shape)
    sobY = np.zeros(images.shape)
    OUT = np.zeros(images.shape)
    for img in range(images.shape[0]):
        sobX[img,:,:] = ndimage.sobel(images[img,:,:],axis=0,mode='constant')
        sobY[img,:,:] = ndimage.sobel(images[img,:,:],axis=1,mode='constant')
        OUT[img,:,:] = np.hypot(sobX[img,:,:],sobY[img,:,:])
        # scale to range [0,1]
        OUT[img,:,:] = (OUT[img,:,:]-np.min(OUT[img,:,:])) / (np.max(OUT[img,:,:])-np.min(OUT[img,:,:]))
    return OUT


import json
import os
import time
from datetime import date, datetime
from typing import Tuple

import boto3
import pandas as pd
from botocore.exceptions import ClientError

s3 = boto3.resource('s3')
dynamodb = boto3.resource('dynamodb')

history_table_name = os.environ['DOG_HISTORY_TABLE_NAME']
summary_table_name = os.environ['DOG_SUMMARY_TABLE_NAME']

def get_dogs(dog_list_json: dict) -> Tuple[dict, date]:
    json_packet = json.loads(dog_list_json)
    dogs_json = json_packet['dogs']
    count_date = datetime.utcfromtimestamp(json_packet['report_date'])
    # Set UTC time to noon, so the local date portion will be on the same day for US timezones.
    count_date = count_date.replace(hour=12, minute=0, second=0, microsecond=0)

    return dogs_json, count_date

def get_dog_dataframe(dogs_json: dict, count_date: date) -> pd.DataFrame:
    dogs_df = pd.DataFrame(dogs_json)
    dogs_df['record_date'] = count_date
    dogs_df['name'] = dogs_df.index
    dogs_df.set_index(['id', 'record_date'], inplace=True)
    dogs_df.index.set_names(['animal_id', 'record_date'], inplace=True)
    return dogs_df

def write_dogs_to_daily_table(dogs_df: pd.DataFrame) -> pd.DataFrame:
    daily_table = dynamodb.Table(history_table_name)
    dogs_flat = pd.DataFrame(dogs_df.to_records())
    dogs_flat['record_date'] = dogs_flat.record_date.apply(lambda rd: int(rd.timestamp()))
    dogs_dict = dogs_flat.to_dict(orient='index')
    count = 1
    for rec in dogs_dict.values():
        daily_table.put_item(Item=rec)
        if count % 50 == 0:
            time.sleep(1)
        count += 1
    return dogs_flat

def write_dogs_to_summary_table(dogs_df: pd.DataFrame):
    summary_table = dynamodb.Table(summary_table_name)
    dog_summary_df = dogs_df.copy()
    dog_summary_df.sort_values(['animal_id', 'record_date'], inplace=True)
    dog_summary_df.drop(
        ['location', 'holder', 'bite', 'kc', 'level_note', 'stress', 'stress_note', 'team', 'diet', 'dbs', 'notes'],
        axis=1, inplace=True)
    dog_summary_df.drop_duplicates(subset=['animal_id'], keep='last', inplace=True)
    dogs_summary_dict = dog_summary_df.to_dict(orient='index')

    count = 1
    for rec in dogs_summary_dict.values():
        try:
            summary_entry = summary_table.get_item(
                Key={
                    'animal_id': rec['animal_id']
                }
            )
            if summary_entry.get('Item') is None:
                rec['days_on_campus'] = 1
                summary_table.put_item(Item=rec)
            else:
                response = summary_table.update_item(
                    Key={
                        'animal_id': rec['animal_id']
                    },
                    UpdateExpression="SET #level = :dbs_level, \
                                       #name = :animal_name, \
                                       weight = :weight, \
                                       record_date = :rec_date, \
                                       age = :age \
                                       ADD days_on_campus :val",
                    ExpressionAttributeNames={
                        '#level': 'Level',
                        '#name': 'name'
                    },
                    ExpressionAttributeValues={
                        ':dbs_level': rec['Level'],
                        ':val': 1,
                        ':animal_name': rec['name'],
                        ':weight': rec['weight'],
                        ':rec_date': rec['record_date'],
                        ':age': rec['age']
                    },
                    ConditionExpression=":rec_date > record_date",
                    ReturnValues='UPDATED_NEW'
                )
        except ClientError as e:
            print(e)
            break
        if count % 30 == 0:
            time.sleep(1)
        count += 1

def lambda_handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    file = event['Records'][0]['s3']['object']['key']
    print(bucket, file)
    dog_list = s3.Object(bucket, file)
    dog_list_json = dog_list.get()['Body'].read().decode('utf-8')
    dogs, report_time = get_dogs(dog_list_json)
    dogs_df = get_dog_dataframe(dogs, report_time)
    dog_history_df = write_dogs_to_daily_table(dogs_df)
    write_dogs_to_summary_table(dog_history_df)

    return {
        'statusCode': 200,
        'body': json.dumps(f'Data loaded to {history_table_name} and {summary_table_name} tables')
    }


class House(object):
    """
    This is the House class. In this object, all features of each house type
    are defined.
    """
    def __init__(self, id, name, length, width, price, min_space, value_increase):
        self.id = id
        self.name = name
        self.length = length
        self.width = width
        self.price = price
        self.min_space = min_space
        self.value_increase = value_increase

    def __str__(self):
        return(str(self.id) + self.name, self.length, self.width, self.price, self.min_space, self.value_increase)


from pylatex import Document, Section, Subsection, Tabular, MultiColumn,\
    MultiRow, NoEscape
from pylatex.math import Math
from collections import OrderedDict
import copy
import numpy as np

from modelguidedattacks.results import build_full_results_dict

def result_to_str(result, long=False):
    if result is None or np.isinf(result) or np.isnan(result):
        return "-"
    elif long:
        return f"{result:.4f}"
    else:
        return f"{result:.2f}"

"""
results top level will be keyed by K
next level will be binary search steps
next level will be keyed by iterations
next level will be keyed by method
"""

only_mean = False
model_name = "resnet50"
results = build_full_results_dict(model_name)

model_to_tex = {
    "resnet50": "Resnet-50",
    "densenet121": "Densenet121",
    "deit_small": "DeiT-S",
    "vit_base": "ViT$_{B}$"
}

# Preprocess all results and select bests
for top_k, bs_dict in results.items():
    for num_bs, iter_dict in bs_dict.items():
        for num_iter, method_dict in iter_dict.items():
            metric_bests = {}
            metrics_compared = {}

            for method_name, method_results in method_dict.items():
                for metric_name, metric_value in method_results.items():
                    reduction_func = max if "ASR" in metric_name else min

                    if metric_name not in metric_bests:
                        metric_bests[metric_name] = 0. if reduction_func is max else np.Infinity
                        metrics_compared[metric_name] = 0

                    if metric_value is not None:
                        metric_bests[metric_name] = reduction_func(metric_bests[metric_name], metric_value)
                        metrics_compared[metric_name] += 1

            for method_name, method_results in method_dict.items():
                for metric_name, metric_value in method_results.items():
                    method_results[metric_name] = result_to_str(metric_value, "inf" in metric_name or "ASR" in metric_name)

                    if metric_value is not None and np.allclose(metric_value, metric_bests[metric_name]) \
                        and metrics_compared[metric_name] > 1:
                        method_results[metric_name] = rf"\textbf{{ {method_results[metric_name]} }}"

method_tex = {
    "cwk": r"CW^K",
    "ad": r"AD",
    "cvxproj": r"\textbf{QuadAttac$K$}"
}

doc = Document("multirow")

protocol_cols = 1
attack_method_cols = 1
best_cols = 4
mean_cols = 4
worst_cols = 4

if only_mean:
    col_widths = [protocol_cols, attack_method_cols, mean_cols]
else:
    col_widths = [protocol_cols, attack_method_cols, best_cols, mean_cols, worst_cols]

total_cols = sum(col_widths)
tabular_string = "|"

for w in col_widths:
    tabular_string += "l" * w + "|"

table1 = Tabular(tabular_string)
table1.add_hline()
table1.add_row((MultiColumn(total_cols, align='|c|', data=NoEscape(model_to_tex[model_name])),))
table1.add_hline()

if only_mean:
    table1.add_row((
        MultiRow(2, data="Protocol"),
        MultiRow(2, data="Attack Method"),
        MultiColumn(mean_cols, align="|c|", data="Mean"),
    ))
else:
    table1.add_row((
        MultiRow(2, data="Protocol"),
        MultiRow(2, data="Attack Method"),
        MultiColumn(best_cols, align="|c|", data="Best"),
        MultiColumn(mean_cols, align="|c|", data="Mean"),
        MultiColumn(worst_cols, align="|c|", data="Worst"),
    ))

table1.add_hline(start=protocol_cols + attack_method_cols + 1)

num_result_colums = 1 if only_mean else 3
table1.add_row("",
               "",
               *(NoEscape(r"ASR$\uparrow$"),
               NoEscape(r"$\ell_1 \downarrow$"),
               NoEscape(r"$\ell_2 \downarrow$"),
               NoEscape(r"$\ell_{\infty} \downarrow$"))*num_result_colums
               )

table1.add_hline()

for top_k, bs_dict in results.items():

    total_results = 0
    # Count total results
    for _, iter_dict in bs_dict.items():
        for num_iter, method_dict in iter_dict.items():
            total_results += len(method_dict)

    top_k_latex_obj = MultiRow(total_results, data=f"Top-{top_k}")

    shown_topk_obj = False

    for bs_steps, iter_dict in bs_dict.items():
        for num_iter, method_dict in iter_dict.items():
            for method_name, method_results in method_dict.items():
                first_obj = top_k_latex_obj if not shown_topk_obj else ""
                shown_topk_obj = True

                row_results = []

                reduction_names = ["mean"] if only_mean else ["best", "mean", "worst"]
                for reduction in reduction_names:
                    for metric in ["ASR", "L1", "L2", "L_inf"]:
                        result_key = f"{metric}_{reduction}"
                        long_result = "inf" in metric
                        row_results.append(
                            NoEscape(method_results[result_key])
                            )

                table1.add_row(
                    first_obj,
                    NoEscape("$" + method_tex[method_name] +
                            f"_{{{bs_steps}x{num_iter}}}$"),
                    *row_results
                )

            table1.add_hline(start=protocol_cols + 1)

    table1.add_hline()

# doc.append(table1)

print(table1.dumps())


import numpy as np
from sklearn.tree import DecisionTreeClassifier

class TreeDiscretizer:
    """A DecisionTreeClassifier of which the leaf indices are used as cluster indices.

    Parameters
    ----------
    X_train : array-like, shape (n_samples, n_features), floats
        The feature matrix of the training set.

    y_train : array-like, shape (n_samples), nonnegative ints
        The labels of X_train.

    J : int
        The maximum number of desired clusters.

    criterion : string, optional
        The split criterion of the underlying DecisionTreeClassifier, 'gini' by default.

    seed : nonnegative int, optional
        This seed for the random number generator makes random splits reproducible.
    """
    def __init__(self, X_train, y_train, J, criterion = 'gini', seed = None):
        self.classifier = DecisionTreeClassifier(
          max_leaf_nodes = J,
          criterion = criterion,
          random_state = seed
        )
        self.classifier.fit(X_train, y_train)
        x_train = self.classifier.apply(X_train)
        self.indexmap = dict(zip(np.unique(x_train), range(len(np.unique(x_train)))))
    def discretize(self, X):
        x_raw = self.classifier.apply(X) # return the raw leaf indices of X
        return np.array([ self.indexmap[x] for x in x_raw ])

def fit_pdf(x, bins = None, normalize = True):
    """Estimate the discrete probability density function (pdf) g of the observed values x.

    Parameters
    ----------
    x : array-like, shape (n_samples,), nonnegative ints
        The indices of the J observed clusters.

    bins : array-like, shape (J,), nonnegative ints, optional
        The J indices of the observed clusters, i.e. the unique values of x.

    normalize : boolean, optional
        True, if the result g should be normalized to a probability density function.
        Otherwise, the integer counts of each bin are returned.

    Returns
    ----------
    g : array-like, shape (J,), floats
       The empirical discrete pdf of the observed values x.
    """
    if bins is None:
        bins = range(np.min(x), np.max(x)+1)
    bincounts = np.bincount(x, minlength = np.max(bins)+1)[bins]
    return normalizepdf(bincounts) if normalize else bincounts