import os
import sys
sys.path.append(os.getcwd())

import torch
import torch.nn as nn
import numpy as np
from itertools import product
import time
import copy
from helper import *

torch.set_default_dtype(torch.float)

np.random.seed(609)
torch.manual_seed(609)

# bandit stuff
Q = torch.tensor([1.5, 2., 2.])
n_actions = Q.numel()

# hyperparameters
learnQ = False
STEPS = 1000
OPTIMIZERS = ["adam", "sgd", "rmsprop"]
OPTIMS = {"adam": torch.optim.Adam, "rmsprop": torch.optim.RMSprop, "sgd": torch.optim.SGD}
LRS = [1e-2, 5e-3]
KL = ["reverse", "forward"]
TAUS = [0, 0.01, 0.05, 0.1, 1]

n_samples = 1000 # for the option of sampling points
LOGITSPACE = (-1, 1)

n_total_experiments = np.prod([len(a) for a in [KL, LRS, OPTIMIZERS, TAUS]])
n_done = 0

curr_exp = int(sys.argv[1])

accum = 1
params = []
for ix, l in enumerate([KL, LRS, OPTIMIZERS, TAUS]):
    params.append(l[(curr_exp // accum) % len(l)])
    accum *= len(l)
direction, lr, optim_name, tau = params
print(params)

# reset the init
logits = get_random_inits(LOGITSPACE, n_samples * n_actions)
n_inits = n_samples
logits = init_params(logits.reshape((n_actions, n_samples)))
# print(logits)

hidden = 100
Q_approx = batch_Q_approx(hidden, n_samples)
Q_optim = OPTIMS[optim_name](params = Q_approx.parameters(), lr = 1e-4)

# setup
exp_name = "{}_lr={}_optim={}_temp={}".format(direction, lr, optim_name, tau)
print("running {} | {} / {}".format(exp_name, curr_exp + 1, n_total_experiments))
print("learnQ = {}".format(learnQ))
optim = OPTIMS[optim_name](params = [logits], lr = lr)

# for recording values
prob_values = []
loss_values = []
t_start = time.time()

print("total param sets = {}".format(n_inits))

if tau != 0:
    normed_arg = Q / tau - torch.max(Q / tau)
    BQ = torch.exp(normed_arg) / torch.sum(torch.exp(normed_arg))
else:
    BQ = torch.tensor([0, 1/2, 1/2])
BQ.unsqueeze_(-1)
Q.unsqueeze_(-1)
QA = Q
# max_action = 3
max_action = torch.tensor([n_actions - 1] * n_inits)
for step in range(STEPS):
    if learnQ is True:
        # if using batch_Q_approx, then shape is (n_inits, n_actions) before permutation
        QA = Q_approx.BQ_forward().squeeze().detach().permute(1, 0)
        # evaluate max action at all the points
        max_action = torch.max(QA, dim = 0)[1]
        if tau != 0:
            # batch approx
            max_Q = QA.max(0, keepdim=True)[0]
            partition = torch.sum(torch.exp((QA - max_Q) / tau), dim = 0)
            BQ = torch.exp((QA - max_Q) / tau) / partition
            assert BQ.shape == (n_actions, n_inits), BQ.shape

            assert torch.isnan(BQ).sum() == 0
    if (step + 1) % 50 == 0:
        print("step = {}".format(step + 1))
    loss = 0

    # get a batch pdf with all the actions
    max_logits = torch.max(logits, dim = 0)[0]
    pi = torch.exp(logits - max_logits) / torch.sum(torch.exp(logits - max_logits), dim = 0, keepdim=True)
    prob_values.append(pi.detach().numpy().copy())
    assert pi.shape == (n_actions, n_inits), print(pi.shape)

    # add N(0, 1) noise to QA for gaussianness
    QA += torch.normal(mean = torch.zeros_like(QA), std = torch.ones_like(QA))

    # compute losses
    if direction == "reverse":
        if tau == 0:
            losses = -torch.sum(QA * pi, dim = 0)
        else:
            losses = torch.sum(pi * approx_log(pi / (BQ + 1e-5)), dim = 0)
    elif direction == "forward":
        if tau == 0:
            # print(max_action.unsqueeze(0).shape, pi.shape)
            max_pis = torch.gather(pi, 0, max_action.unsqueeze(0))
            assert max_pis.numel() == n_inits, max_pis.shape
            losses = -approx_log(max_pis)
        else:
            losses = torch.sum(BQ * approx_log(BQ / (pi + 1e-5)), dim = 0)

    # assert losses.shape[0] == n_inits, losses.shape
    assert losses.numel() == n_inits, losses.shape
    loss_values.append(losses.squeeze().detach().numpy().copy())
    optim.zero_grad()
    loss = losses.sum()
    assert torch.isnan(loss) == 0, losses[losses != losses].numel()
    # print(losses.mean())
    # if (losses.mean() == 0):
    # print(losses.mean())
    loss.backward()
    optim.step()

    if learnQ is True:
        # draw an action from the current policy
        # is it reasonable to use just one critic network? maybe batch over all the initializations at first?
        with torch.no_grad():
            actions = sample_boltzmann(pi)
        assert actions.numel() == n_inits

        # batch
        QA = Q_approx.BQ_forward().squeeze().permute(1, 0)
        # QA now of shape (n_actions, n_inits)
        QA = torch.gather(QA, 0, actions.unsqueeze(0))
        assert QA.numel() == actions.numel()
        # assert QA_approx.shape == (actions.shape[0], n_inits), QA_approx.shape
        Q_losses = (Q[actions, :].squeeze() - QA.squeeze()).pow(2)
        assert Q_losses.numel() == n_inits, (QA.shape, Q[actions].shape)
        Q_loss = Q_losses.mean()
        assert torch.isnan(Q_loss) == 0
        Q_optim.zero_grad()
        Q_loss.backward()
        Q_optim.step()
t_end = time.time()
print("took {}s".format(t_end - t_start))
n_done += 1
max_logits = torch.max(logits, dim = 0)[0]
final_pdfs = torch.exp(logits - max_logits) / torch.sum(torch.exp(logits - max_logits), dim = 0, keepdim=True)
assert final_pdfs.shape == (n_actions, n_inits)

# save values
logit_values = np.array(prob_values)
loss_values = np.array(loss_values)
# print(mu_values[0, :], mu_values[-1, :])
foldername = ""
if learnQ is True:
    # should record final learnQ in this case too
    foldername += "learnQ"
else:
    foldername += "notlearnQ"
write_dir = "data/discrete_bandit/{}/".format(foldername)
os.makedirs(write_dir, exist_ok=True)
np.save(write_dir + exp_name + "_BQ.npy", BQ.squeeze().detach().numpy())
np.save(write_dir + exp_name + "_pdf.npy", final_pdfs.detach().numpy())
np.save(write_dir + exp_name + "_prob.npy", prob_values)
np.save(write_dir + exp_name + "_loss.npy", loss_values)


from numpy import array, zeros, unique, searchsorted, arange, pi

from pyNastran.dev.bdf_vectorized.cards.elements.property import Property

#from pyNastran.bdf.field_writer_8 import set_blank_if_default
from pyNastran.bdf.field_writer_8 import print_card_8
from pyNastran.bdf.bdf_interface.assign_type import (integer,
    double, double_or_blank)

class PTUBE(Property):
    type = 'PTUBE'

    def __init__(self, model):
        """
        Defines the PTUBE object.

        Parameters
        ----------
        model : BDF
           the BDF object

        """
        Property.__init__(self, model)

    def allocate(self, ncards):
        self.n = ncards
        self.model.log.debug('%s ncards=%s' % (self.type, ncards))
        float_fmt = self.model.float_fmt
        #: Property ID
        self.property_id = zeros(ncards, 'int32')
        self.material_id = zeros(ncards, 'int32')

        self.OD = zeros((ncards, 2), float_fmt)
        self.t = zeros(ncards, float_fmt)
        self.nsm = zeros(ncards, float_fmt)

    def add_card(self, card, comment=''):
        self.model.log.debug('n=%s i=%s' % (self.n, self.i))
        i = self.i
        self.property_id[i] = integer(card, 1, 'property_id')
        self.material_id[i] = integer(card, 2, 'material_id')
        OD1 = double(card, 3, 'OD1')
        t = double_or_blank(card, 4, 't')
        if t is None:
            t = OD1 / 2.
        self.t[i] = t
        self.nsm[i] = double_or_blank(card, 5, 'nsm', 0.0)
        OD2 = double_or_blank(card, 6, 'OD2', OD1)
        self.OD[i, :] = [OD1, OD2]
        assert len(card) <= 7, 'len(PTUBE card) = %i\ncard=%s' % (len(card), card)
        self.i += 1

    def build(self):
        """
        :param cards: the list of PTUBE cards
        """
        if self.n:
            i = self.property_id.argsort()
            self.property_id = self.property_id[i]
            self.material_id = self.material_id[i]
            self.OD = self.OD[i, :]
            self.t = self.t[i]
            self.nsm = self.nsm[i]

            unique_pids = unique(self.property_id)
            if len(unique_pids) != len(self.property_id):
                raise RuntimeError('There are duplicate PTUBE IDs...')
            self._cards = []
            self._comments = []
        else:
            self.property_id = array([], dtype='int32')

    def update(self, maps):
        """
        maps = {
            'property' : pid_map,
            'material' : mid_map,
        }
        """
        if self.n:
            nid_map = maps['node']
            mid_map = maps['material']
            for i, (pid, mid) in enumerate(zip(self.property_id, self.material_id)):
                self.property_id[i] = pid_map[pid]
                self.material_id[i] = mid_map[mid]

    #=========================================================================

    def get_mass_per_length_by_property_id(self, property_id=None):
        # L * (A * rho + nsm)
        i = self.get_property_index_by_property_id(property_id)
        A = self.A[i]
        mid = self.material_id[i]
        #mat = self.model.materials.get_material(mid)
        rho = self.model.materials.get_density_by_material_id(mid)
        nsm = self.nsm[i]
        return A * rho + nsm

    def get_area_by_property_id(self, property_id=None):
        i = self.get_property_index_by_property_id(property_id)
        return self.get_area_by_property_index(i)

    def get_area_by_property_index(self, i=None):
        area = zeros(len(i), dtype='float64')
        for ni, ii in enumerate(i):
            A = (self._area1(ii) + self._area2(ii)) / 2.
            area[ni] = A
        return area

    def _area1(self, i):
        """Gets the Area of Section 1 of the CTUBE."""
        Dout = self.OD[i, 0]
        if self.t[i] == 0:
            return pi / 4. * Dout**2
        Din = Dout - 2 * self.t
        A1 = pi / 4. * (Dout * Dout - Din * Din)
        return A1

    def _area2(self, i):
        """Gets the Area of Section 2 of the CTUBE."""
        Dout = self.OD[i, 1]
        if self.t[i] == 0:
            return pi / 4. * Dout**2
        Din = Dout - 2 * self.t
        A2 = pi / 4. * (Dout * Dout - Din * Din)
        return A2

    def get_non_structural_mass_by_property_id(self, property_id=None):
        i = self.get_property_index_by_property_id(property_id)
        nsm = self.nsm[i]
        return nsm

    #def get_E_by_property_id(self, property_id=None):
        #i = self.get_property_index_by_property_id(property_id)
        #material_id = self.material_id[i]
        #E = self.model.materials.get_E_by_material_id(material_id)
        #return E

    def get_E_by_property_id(self, property_id=None):
        mid = self.get_material_id_by_property_id(property_id)
        E = self.model.materials.get_E_by_material_id(mid)
        return E

    #def get_G_by_property_id(self, property_id=None):
        #i = self.get_property_index_by_property_id(property_id)
        #material_id = self.material_id[i]
        #G = self.model.materials.get_G_by_material_id(material_id)
        #return G

    def get_G_by_property_id(self, property_id=None):
        mid = self.get_material_id_by_property_id(property_id)
        G = self.model.materials.get_G_by_material_id(mid)
        return G

    def get_J_by_property_id(self, property_id=None):
        i = self.get_property_index_by_property_id(property_id)
        return self.get_J_by_property_index(i)

    def get_J_by_property_index(self, i=None):
        J = []
        for ni, ii in enumerate(i):
            Ji = self._Ji(ii)
            J.append(Ji)
        return array(J, dtype='float64')

    def _Ji(self, i):
        Dout = self.OD[i, 0]
        if self.t[0] == 0.0:
            return pi / 8. * Dout**4
        Din = Dout - 2 * self.t[i]
        return pi / 8. * (Dout**4 - Din**2)

    def get_c_by_property_id(self, property_id=None):
        i = self.get_property_index_by_property_id(property_id)
        c = self.c[i]
        return c

    def get_material_id_by_property_id(self, property_id=None):
        i = self.get_property_index_by_property_id(property_id)
        mid = self.material_id[i]
        return mid

    #=========================================================================

    def get_density_by_property_id(self, property_id=None):
        mid = self.get_material_id_by_property_id(property_id)
        density = self.model.materials.get_density_by_material_id(mid)
        return density

    #def get_J_by_property_id(self, property_id=None):
        #mid = self.get_material_id_by_property_id(property_id)
        #J = self.model.materials.get_J_by_material_id(mid)
        #return J

    #def get_E_by_property_id(self, property_id=None):
        #mid = self.get_material_id_by_property_id(property_id)
        #E = self.model.materials.get_E_by_material_id(mid)
        #return E

    #=========================================================================

    def write_card(self, bdf_file, size=8, property_id=None):
        if self.n:
            if self.n:
                if property_id is None:
                    i = arange(self.n)
                else:
                    assert len(unique(property_id)) == len(property_id), unique(property_id)
                    i = searchsorted(self.property_id, property_id)

            for (pid, mid, (OD1, OD2), t, nsm) in zip(
                 self.property_id, self.material_id[i], self.OD[i, :], self.t[i], self.nsm[i]):

                #t = set_blank_if_default(t, OD1 / 2.)
                #nsm = set_blank_if_default(nsm, 0.0)
                #OD2 = set_blank_if_default(OD2, OD1)

                card = ['PTUBE', pid, mid, OD1, t, nsm, OD2]
                bdf_file.write(print_card_8(card))

    def slice_by_index(self, i):
        i = self._validate_slice(i)
        obj = PTUBE(self.model)
        n = len(i)
        obj.n = n
        obj.i = n
        #obj._cards = self._cards[i]
        #obj._comments = obj._comments[i]
        #obj.comments = obj.comments[i]
        obj.property_id = self.property_id[i]
        obj.material_id = self.material_id[i]
        obj.OD = self.OD[i, :]
        obj.t = self.t[i]
        obj.nsm = self.nsm[i]
        return obj


# -*-coding:Utf-8 -*

import os
import pickle
import re
from classes.labyrinthe import Labyrinthe

class Partie:

    """Controlleur de partie.

    Il nous permet de controller le robot et de sauvegarder l'état de la partie.

    """

    obstacles = ['O']               # Liste des obstacles
    sortie = 'U'                    # Sortie du labyrinthe

    def __init__(self, nom, labyrinthe):
        self.nom = nom
        self.lab = labyrinthe
        self.en_cours = False
        self.gagnee = False

    @classmethod
    def charger(self, nom_fichier):
        """Chargement de la partie sauvegardée."""
        with open(nom_fichier, "rb") as ficher_sauvegarde:
            unpickler = pickle.Unpickler(ficher_sauvegarde)
            partie = unpickler.load()
        return partie

    def sauvegarder(self, nom_fichier):
        """Sauvegarde la partie en cours."""
        with open(nom_fichier, "wb") as ficher_sauvegarde:
            pickler = pickle.Pickler(ficher_sauvegarde)
            pickler.dump(self)

    def supprimer(self, nom_fichier):
        """Supprime le fichier de sauvegarde """
        if os.path.exists("sauvegarde"):
            os.remove("sauvegarde")

    def deplacer_robot(self, robot, commande):
        """ Déplacement du robot du joueur.

        Modifie les coordonnées du robot après avoir vérifié l'absence
        d'obstacles et renvoie True si tel est le cas.
        Met fin à la partie si le robot atteint la sortie.

        """
        mouvement = 0                   # Nombre de cases parcourues

        # Détection d'une distance éventuelle
        try:
            distance = int(commande[1:])
        except:
            distance = 1

        # Pour chaque unité de mouvement
        while distance != 0:

            # Conversion numérique de la direction saisie
            if commande[0].upper() == 'N':
                direction = (-1, 0)
            elif commande[0].upper() == 'E':
                direction = (0, 1)
            elif commande[0].upper() == 'S':
                direction = (1, 0)
            elif commande[0].upper() == 'O':
                direction = (0, -1)
            else:
                break

            # Calcul de la nouvelle position
            pos = [self.lab.robots[robot][0] + direction[0],
                   self.lab.robots[robot][1] + direction[1]]

            # On verifie que la position ne rencontre pas d'obstacle.
            if self.lab.grille[pos[0]][pos[1]] in Partie.obstacles:
                break

            # Assignation de la nouvelle position
            self.lab.robots[robot] = pos
            distance-=1
            mouvement+=1

            # La sortie a été atteinte.
            if self.lab.grille[pos[0]][pos[1]] == Partie.sortie:
                # Fin du jeu
                self.gagnee = True
                break

        if mouvement == 0:
            return False
        else:
            return True

    def emmurer(self, robot, commande):
        """ Emmurer un autre joueur.

        Transforme une porte en mur ou un mur en porte en vérifiant
        que le mur est à proximité du joueur et qu'il ne s'agit pas
        d'un des bords du labyrinthe.

        """

        # Conversion numérique de la direction saisie
        if commande[1].upper() == 'N':
            direction = (-1, 0)
        elif commande[1].upper() == 'E':
            direction = (0, 1)
        elif commande[1].upper() == 'S':
            direction = (1, 0)
        elif commande[1].upper() == 'O':
            direction = (0, -1)
        else:
            return False

        # Calcul la position relative à modifier
        pos = [self.lab.robots[robot][0] + direction[0],
               self.lab.robots[robot][1] + direction[1]]

        # S'il ne s'agit pas d'un bord du labyrinthe
        if (pos[0] < len(self.lab.grille ) - 1 and
            pos[1] < len(self.lab.grille[0]) - 1 and
            pos[0] > 0 and pos[1] > 0):

            if (commande[0].upper() == 'M' and
                self.lab.grille[pos[0]][pos[1]] == '.'):

                # Il s'agit d'une porte qu'on peut emmurer
                self.lab.grille[pos[0]][pos[1]] = 'O'

            elif (commande[0].upper() == 'P' and
                  self.lab.grille[pos[0]][pos[1]] == 'O'):

                # Il s'agit d'un mur qu'on peut détruire
                self.lab.grille[pos[0]][pos[1]] = '.'

            else:
                return False
        else:
            return False

        return True


#!/usr/bin/env python
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
#                               Alex Dementsov
#                      California Institute of Technology
#                        (C) 2009  All Rights Reserved
#
# {LicenseText}
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#

"""
QEConvergenceTask - table that keeps many-to-many relationship between QEConvergence
and QETask tables

Notes:
    - None
"""

from vnf.components.QETable import QETable

class QEConvParamTask(QETable):

    name = "qeconvparamtasks"
    import dsaw.db

    convparamid    = dsaw.db.varchar(name="convparamid", length=64)
    convparamid.constraints = 'REFERENCES qeconvparams (id)'    # Important
    convparamid.meta['tip'] = "convparamid"

    taskid    = dsaw.db.varchar(name="taskid", length=64)
    taskid.constraints = 'REFERENCES qetasks (id)'    # Important
    taskid.meta['tip'] = "Task id"

__date__ = "$Apr 22, 2010 12:25:44 PM$"


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import numpy as np
import elpigraph
from ..data import g1s_markers, g2m_markers

def find_nonproliferating_cells(adata,
                                nonprolif_frac=0.3,
                                n_nodes=50,
                                max_iter = 20,
                                n_sd = 3.0,
                                Mu = 1.0,
                                verbose = True):
    """ Find non-proliferating cells from the trajectory on cell cycle space

    Parameters
    ----------------------
    adata: AnnData
        AnnData to be annotated. Should be previously pre-processed.
    nonprolif_frac: float
        Initial estimation of fraction of non-proliferating cells
    n_nodes: int
        Number of nodes used for finding the trajectory
    max_iter: float
        Maximum number of iterations of new trajectories to find non-proliferating
        cells
    n_sd: float
        Number of standard deviations of distance that non-proliferating cells
        deviate from trajectory
    Mu: float
        Parameter passed to elpigraph.computeElasticPrincipalCircle
    verbose: bool
        If True, the function will print messages
    """
    all_markers = g1s_markers + g2m_markers
    Xccm = adata[:,list(set(all_markers)&set(adata.var_names))].X
    cc_score = np.array(list(np.mean(Xccm,axis=1)))

    ind_sorted_prolif = np.argsort(cc_score)
    ind_nonprolif = ind_sorted_prolif[0:int(len(adata)*nonprolif_frac)]
    adata.obs['proliferating'] = np.empty(len(adata)).astype(np.bool)
    adata.obs['proliferating'][:] = True
    adata.obs['proliferating'][ind_nonprolif] = False

    # sc.pl.scatter(adata,x='G1-S',y='G2-M',color='proliferating')

    fraction_nonprolif_old = nonprolif_frac

    for i in range(max_iter):
        X_elpigraph_training = adata.obs[['G1-S','G2-M']].to_numpy().astype(np.float64)
        u = X_elpigraph_training.copy()
        X_elpigraph_training = X_elpigraph_training[adata.obs['proliferating'],:]

        egr = elpigraph.computeElasticPrincipalCircle(X_elpigraph_training,n_nodes,
                                                      Mu=Mu,verbose=False)
        partition, dists = elpigraph.src.core.PartitionData(X = u, NodePositions = egr[0]['NodePositions'],
                                                                MaxBlockSize = 100000000, TrimmingRadius = np.inf,
                                                                SquaredX = np.sum(u**2,axis=1,keepdims=1))
        ind_prolif = adata.obs['proliferating']
        mndist = np.mean(dists[ind_prolif])
        intervaldist = np.std(dists[ind_prolif])*n_sd
        tt1 = [not b for b in adata.obs['proliferating']]
        tt2 = [(d>mndist+intervaldist)[0] for d in dists]
        nonprolif_new = np.array(tt1) & np.array(tt2)
        adata.obs['proliferating'] = [not b for b in nonprolif_new]
        fraction_nonprolif = 1-np.sum(adata.obs['proliferating'])/len(adata)
        if verbose:
            print('\n\n===========\nIteration',i,'Fraction of non-proliferating cells:',fraction_nonprolif,'\n==============\n\n\n')
        if np.abs(fraction_nonprolif-fraction_nonprolif_old)<0.01:
            break
        fraction_nonprolif_old = fraction_nonprolif


#AI Assignment 1
#Implement depth first search algorithm and Breadth First Search algorithm. Use an undirected graph and
#develop a recursive algorithm for searching all the vertices of a graph or tree data structure.

#DFS
graph = {
  '5' : ['3','7'],
  '3' : ['2', '4'],
  '7' : ['8'],
  '2' : [],
  '4' : ['8'],
  '8' : []
}

visited = set()

def dfs(visited, graph, node):
    if node not in visited:
        print(node)
        visited.add(node)
        for neighbour in graph[node]:
            dfs(visited, graph, neighbour)

print("Following is the Depth-First Search:")
dfs(visited, graph, '5')

visited = []
queue = []

def bfs(visited, graph, node):
    visited.append(node)
    queue.append(node)

    while queue:
        m = queue.pop(0)
        print(m, end =" ")

        for neighbour in graph[m]:
            if neighbour not in visited:
                visited.append(neighbour)
                queue.append(neighbour)

print("Following is the Breadth-First:")
bfs(visited, graph, '5')


from sklearn.tree import DecisionTreeClassifier
import pandas as pd
import numpy as np
import random
from sklearn.metrics import roc_auc_score
import BoostMain
import matplotlib.pyplot as plt

def load_feature(path):
    df =  pd.read_csv(path, index_col=None, header=None, delimiter=" ")
    df.columns = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n"]
    return df

def load_label(path):
    return pd.read_csv(path, index_col=None, header=None, delimiter=" ")

def main(model_nums=100):
    T = model_nums
    train_feature_path = "./adult_dataset/adult_train_feature.txt"
    train_label_path = "./adult_dataset/adult_train_label.txt"

    train_full_feature = load_feature(train_feature_path)
    train_full_label = load_label(train_label_path)
    feature_names = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n"]
    train_full_feature["label"] = train_full_label

    a = 0
    b = len(train_full_feature)//5
    c = 2*len(train_full_feature)//5
    d = 3*len(train_full_feature)//5
    e = 4*len(train_full_feature)//5
    f = 5*len(train_full_feature)//5
    scale = [a, b, c, d, e, f]
    auc = []
    for i in range(5):
        train_feature = train_full_feature.iloc[list(range(0,scale[i]))+list(range(scale[i+1],scale[-1])),:]
        test_feature = train_full_feature.iloc[scale[i]:scale[i+1],:]
        test_label = train_full_label.iloc[scale[i]:scale[i+1],:].values

        models = list()
        feature_names_used = list()
        for i in range(T):
            train_feature_names_used_onetime = sorted(random.sample(feature_names, 4))
            tmp = train_feature.sample(frac=0.5, replace=True)
            train_label_used_onetime = tmp[["label"]]
            train_feature_used_onetime = tmp[train_feature_names_used_onetime]
            decisiontree_model = DecisionTreeClassifier(criterion="entropy", splitter="best")
            decisiontree_model.fit(train_feature_used_onetime, train_label_used_onetime)
            models.append(decisiontree_model)
            feature_names_used.append(train_feature_names_used_onetime)

        predictions = np.zeros(len(test_label))
        for model, names in zip(models,feature_names_used):
            prediction = model.predict(test_feature[names])
            predictions = predictions+prediction
        else:
            predictions = predictions/len(models)

        auc.append(roc_auc_score(test_label, predictions))
    else:
        return auc

def test(model_nums):
    T = model_nums
    train_feature_path = "./adult_dataset/adult_train_feature.txt"
    train_label_path = "./adult_dataset/adult_train_label.txt"

    test_feature_path = "./adult_dataset/adult_test_feature.txt"
    test_label_path = "./adult_dataset/adult_test_label.txt"

    train_full_feature = load_feature(train_feature_path)
    train_full_label = load_label(train_label_path)
    test_full_feature = load_feature(test_feature_path)
    test_full_label = load_label(test_label_path)
    feature_names = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n"]
    train_full_feature["label"] = train_full_label
    test_full_feature["label"] = test_full_label

    train_feature = train_full_feature
    test_feature = test_full_feature
    test_label = test_full_label.values

    models = list()
    feature_names_used = list()
    for _ in range(T):
        train_feature_names_used_onetime = sorted(random.sample(feature_names, 4))
        tmp = train_feature.sample(frac=0.5, replace=True)
        train_label_used_onetime = tmp[["label"]]
        train_feature_used_onetime = tmp[train_feature_names_used_onetime]
        decisiontree_model = DecisionTreeClassifier(criterion="entropy", splitter="best")
        decisiontree_model.fit(train_feature_used_onetime, train_label_used_onetime)
        models.append(decisiontree_model)
        feature_names_used.append(train_feature_names_used_onetime)

    predictions = np.zeros(len(test_label))
    for model, names in zip(models,feature_names_used):
        prediction = model.predict(test_feature[names])
        predictions = predictions+prediction
    else:
        predictions = predictions/len(models)

    return roc_auc_score(test_label, predictions)

if __name__ == "__main__":
    adaboostAUC = []
    randomForestAUC = []
    x = list(range(1, 101))
    for i in range(1, 101):
        print("第"+str(i)+"次迭代")
        adaboostAUC.append(np.array(BoostMain.main(i)).mean())
        randomForestAUC.append(np.array(main(i)).mean())

    plt.title('AUC Result Analysis')
    plt.plot(x, adaboostAUC, color='green', label='adaboostAUC')
    plt.plot(x, randomForestAUC, color='red', label='randomForestAUC')

    plt.legend() # 显示图例

    plt.xlabel('iteration times')
    plt.ylabel('AUC')
    plt.show()
    bestadanum = adaboostAUC.index(max(adaboostAUC))+1
    bestrandomForestnum = randomForestAUC.index(max(randomForestAUC))+1
    print(bestadanum)
    print(bestrandomForestnum)
    print(BoostMain.test(bestadanum))
    print(test(bestrandomForestnum))


import pygame
import sys
import random

pygame.display.set_caption("Reversi")
pygame.init()
position=()
width = 400
height = 400
red=(255,0,0)
white=(255,255,255)
turno=0
clock = pygame.time.Clock()
window = pygame.display.set_mode((width, height))
Jugadores = [1,2]

Tablero = [ [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 2, 1, 0, 0, 0],
            [0, 0, 0, 1, 2, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0] ]

Copia =   [ [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0] ]

#Nombres Jugadores
nombreJugador1 = input("Ingrese el nombre del jugador 1(Rojo): ")
nombreJugador2 = input("Ingrese el nombre del jugador 2(Blanco): ")
Turno = random.choice(Jugadores)
print('El primer jugador es: ' +str(Turno))

#Variables
fichas = 60
movimientos = 0

def boardPos (mouseX, mouseY):
    if (mouseY < 50):
        row = 0
    elif (mouseY < 100):
        row = 1
    elif (mouseY <150):
        row = 2
    elif (mouseY < 200):
        row = 3
    elif (mouseY <250):
        row = 4
    elif (mouseY <300):
        row = 5
    elif (mouseY <350):
        row = 6
    elif (mouseY < 400):
        row = 7
    if (mouseX < 50):
        col = 0
    elif (mouseX < 100):
        col = 1
    elif (mouseX <150):
        col = 2
    elif (mouseX < 200):
        col = 3
    elif (mouseX <250):
        col = 4
    elif (mouseX <300):
        col = 5
    elif (mouseX <350):
        col = 6
    elif (mouseX < 400):
        col = 7
    return (row, col)

def esValida(A:[int],B:[int],i:int,j:int,turneto:int)->bool:
    Valida=False
    if A[i][j]!=0:
        pass
    elif A[i][j] == 0:
        for a in range (0,8):
            for b in range (0,8):
                B[a][b]=A[a][b]
        consumo(B, i, j,turneto)
        reflejarJugada(B,i,j,turneto)
        for a in range (0,8):
            for b in range (0,8):
                if a==i and b==j:
                    pass
                elif a!=i or b!=j:
                    if A[a][b]==B[a][b]:
                        pass
                    elif A[a][b]!=B[a][b]:
                        Valida=True
    return Valida

def cambiarJugador(turn:int) -> 'void':
    if turn==1:
        turn=2
    elif turn==2:
        turn=1
    return turn

def reflejarJugada( A: [int], i: int, j: int, turno: int) -> 'void':
    A[i][j] = turno

def consumoVertical(A:[int], i:int, j:int, turno:int) -> 'void':
    k=int
    k=i
    if i!=7:
        while i<7:
            if A[i+1][j]!=turno and A[i+1][j]!=0:
                i=i+1
            elif A[i+1][j]==0:
                i=7
            elif A[i+1][j]==turno:
                for t in range (k,i+1):
                    A[t][j]=turno
                i=7
    elif i==7:
        pass
    i=k
    if i!=0:
        while i>0:
            if A[i-1][j]!=turno and A[i-1][j]!=0:
                i=i-1
            elif A[i-1][j]==0:
                i=0
            elif A[i-1][j]==turno:
                for z in range (i-1,k):
                    A[z][j]=turno
                i=0
    elif i==0:
        pass

def consumoHorizontal(A:[int], i:int, j:int, turno:int) -> 'void':
    k=int
    k=j
    if j!=7:
        while j<7:
            if A[i][j+1]!=turno and A[i][j+1]!=0:
                j=j+1
            elif A[i][j+1]==0:
                j=7
            elif A[i][j+1]==turno:
                for t in range (k,j+1):
                    A[i][t]=turno
                j=7
    elif j==7:
        pass
    j=k
    if j!=0:
        while j>0:
            if A[i][j-1]!=turno and A[i][j-1]!=0:
                j=j-1
            elif A[i][j-1]==0:
                j=0
            elif A[i][j-1]==turno:
                for z in range (j-1,k):
                    A[i][z]=turno
                j=0
    elif j==0:
        pass

def consumoDiagonal(A:[int], i:int, j:int, turno:int) -> 'void':
    k = i
    l = j
    if i != 0 and j != 7:
        while i > 0 and j < 7:
            if A[i-1][j+1] != turno and A[i-1][j+1] != 0:
                i = i - 1
                j = j + 1
            elif A[i-1][j+1] == 0:
                i = 0
                j = 7
            elif A[i-1][j+1] == turno:
                i = k
                for r in range(l,j+1):
                    A[i][r] = turno
                    i = i - 1
                i = 0
                j = 7
    elif i == 0 or j == 7:
        pass

    i = k
    j = l

    if i != 7 and j != 7:
        while i <7 and j <7:
            if A[i+1][j+1] != turno and A[i+1][j+1] != 0:
                i = i + 1
                j = j + 1
            elif A[i+1][j+1] == 0:
                i = 7
                j = 7
            elif A[i+1][j+1] == turno:
                i = k
                for r in range(l,j+1):
                    A[i][r] = turno
                    i = i + 1
                i = 7
                j = 7
    elif i == 7 or j == 7:
        pass

    i=k
    j=l

    if i != 7 and j != 0:
        while i < 7 and j > 0:
            if A[i+1][j-1] != turno and A[i+1][j-1] != 0:
                i = i + 1
                j = j - 1
            elif A[i+1][j-1] == 0:
                i = 7
                j = 0
            elif A[i+1][j-1] == turno:
                j = l
                for r in range(k,i+1):
                    A[r][j] = turno
                    j = j - 1
                i = 7
                j = 0
    elif i == 7 or j == 0:
        pass

    i=k
    j=l

    if i != 0 and j != 0:
        while i > 0 and j > 0:
            if A[i-1][j-1] != turno and A[i-1][j-1] != 0:
                i = i - 1
                j = j - 1
            elif A[i-1][j-1] == 0:
                i = 0
                j = 0
            elif A[i-1][j-1] == turno:
                for r in range(i-1,k):
                    A[r][j-1] = turno
                    j = j + 1
                i = 0
                j = 0
    elif i == 0 or j == 0:
        pass

def quedanFichas(F:int,R:int)->bool:
    if F-R==0:
        quedan=False
    elif F-R!=0:
        quedan=True
    return quedan

def consumo(A:[int], i:int, j:int, turno:int) -> 'void':
    consumoDiagonal(A, i, j, Turno)
    consumoHorizontal(A, i, j, Turno)
    consumoVertical(A, i, j, Turno)

def QuedanJugadas(A:[int],B:[int],turno:int)->bool:
    Quedan=False
    for x in range(0,8):
        for y in range (0,8):
            if A[x][y]==0:
                if esValida(A,B,x,y,turno):
                    Quedan=True
                else:
                    pass
            elif A[x][y]==1 or A[x][y]==2:
                pass
    return Quedan

game_over = False

pygame.draw.line(window, (255,255,255),(50,400),(50,0),2)
pygame.draw.line(window, (255,255,255),(100,400),(100,0),2)
pygame.draw.line(window, (255,255,255),(150,400),(150,0),2)
pygame.draw.line(window, (255,255,255),(200,400),(200,0),2)
pygame.draw.line(window, (255,255,255),(250,400),(250,0),2)
pygame.draw.line(window, (255,255,255),(300,400),(300,0),2)
pygame.draw.line(window, (255,255,255),(350,400),(350,0),2)
pygame.draw.line(window, (255,255,255),(0,50),(400,50),2)
pygame.draw.line(window, (255,255,255),(0,100),(400,100),2)
pygame.draw.line(window, (255,255,255),(0,150),(400,150),2)
pygame.draw.line(window, (255,255,255),(0,200),(400,200),2)
pygame.draw.line(window, (255,255,255),(0,250),(400,250),2)
pygame.draw.line(window, (255,255,255),(0,300),(400,300),2)
pygame.draw.line(window, (255,255,255),(0,350),(400,350),2)
pygame.draw.circle(window,red,(175,225),20)
pygame.draw.circle(window,red,(225,175),20)
pygame.draw.circle(window,white,(175,175),20)
pygame.draw.circle(window,white,(225,225),20)

while not game_over:
	for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

            if quedanFichas(fichas, movimientos) == True and (QuedanJugadas(Tablero,Copia,1)==True or QuedanJugadas(Tablero,Copia,2)==True):
                if QuedanJugadas(Tablero,Copia,Turno):
                    if event.type == pygame.MOUSEBUTTONDOWN:
                        (mouseX, mouseY) = pygame.mouse.get_pos()
                        (row, col) = boardPos (mouseX, mouseY)
                        F=row
                        C=col
                        centerX = ((col) * 50)+25
                        centerY = ((row) * 50)+25

                        if Turno==1:
                            color=red

                        elif Turno==2:
                            color=white

                        if esValida(Tablero,Copia,F,C,Turno)==True:
                                pygame.draw.circle(window,color,(centerX,centerY),20)
                                consumo(Tablero, F, C, Turno)
                                reflejarJugada(Tablero, F, C, Turno)
                                Turno = cambiarJugador(Turno)
                                print("El turno es del jugador:", Turno)
                                for i in range (0,8):
                                    for j in range(0,8):
                                        if Tablero[i][j]==1:
                                            color=red
                                            row=i
                                            col=j
                                            centerX = ((col) * 50)+25
                                            centerY = ((row) * 50)+25
                                            pygame.draw.circle(window,color,(centerX,centerY),20)
                                        elif Tablero[i][j]==2:
                                            color=white
                                            row=i
                                            col=j
                                            centerX = ((col) * 50)+25
                                            centerY = ((row) * 50)+25
                                            pygame.draw.circle(window,color,(centerX,centerY),20)
                                        else: pass
                        elif esValida(Tablero,Copia,F,C,Turno)==False:
                            print("La jugada introducida no es valida.")
                            print("Para que una jugada sea valida, la casilla no debe estar ocupada por una ficha y se deben consumir almenos una ficha.")
                else:
                    Ext=Turno
                    Turno = cambiarJugador(Turno)
                    print("El jugador", Ext, "no pude hacer movimientos.")
                    print("El turno es del jugador", Turno)
            else:
                print("Se termina el juego porque no se pueden colocar mas fichas")
                sys.exit()

            pygame.display.update()

	clock.tick(10)


import pennylane as qml
import numpy as np
from quantum_aware_optims import *
import torch
from torch.optim import SGD

n_wires = 2

dev = qml.device("default.qubit", analytic=True, wires=2)

def ansatz(params):
    qml.RX(params[0], wires=0)
    qml.RY(params[1], wires=1)
    qml.CNOT(wires=[0, 1])

@qml.qnode(dev)
def circuit(inputs, params):
    ansatz(params)
    return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliY(1))

@qml.qnode(dev)
def circuit2(inputs, params):
    ansatz(params)
    return qml.expval(qml.PauliX(0))

qcircuits = [circuit, circuit2]
proportions = torch.Tensor([0.5, 1.2, -0.2])
init_params = torch.Tensor([0.1, 0.25])

qlayer = qml.qnn.TorchLayer(circuit,{"params":2})

expvals = qlayer(init_params)
def loss_func(expvals):
    loss = torch.mul(expvals[0],torch.tensor(0.5)) + torch.mul(expvals[1],torch.tensor(0.2))
    return loss

# optim =  SGD([qlayer.params], lr=0.1)
# optimQNG = QuantumNaturalGradientOptim([qlayer.params],circuit, lr=0.1)
# for i in range(100):
#     output = qlayer(qlayer.params)
#     loss = loss_func(output)
#     print(loss)
#     loss.backward()
#     optimQNG.step()
#     optimQNG.zero_grad()
# optim = RotoSolve(init_params,qcircuits,proportions)
# loss = optim.step()
# print(loss)
# print(optim.param_groups)

dev = qml.device("default.qubit", wires=3)

@qml.qnode(dev)
def circuit(inputs, params):
    # |psi_0>: state preparation
    qml.RY(np.pi / 4, wires=0)
    qml.RY(np.pi / 3, wires=1)
    qml.RY(np.pi / 7, wires=2)

    # V0(theta0, theta1): Parametrized layer 0
    qml.RZ(params[0], wires=0)
    qml.RZ(params[1], wires=1)

    # W1: non-parametrized gates
    qml.CNOT(wires=[0, 1])
    qml.CNOT(wires=[1, 2])

    # V_1(theta2, theta3): Parametrized layer 1
    qml.RY(params[2], wires=1)
    qml.RX(params[3], wires=2)

    # W2: non-parametrized gates
    qml.CNOT(wires=[0, 1])
    qml.CNOT(wires=[1, 2])

    return qml.expval(qml.PauliY(0))

qlayer = qml.qnn.TorchLayer(circuit, {"params": 4})

def loss_func(theta):
    loss = qlayer(theta)
    return loss

params = np.array([0.5, -0.123, 0.543, 0.233])
qlayer.params.data = torch.tensor(params)
optimQNG = QuantumNaturalGradientOptim([qlayer.params], circuit, lr=0.1)
for i in range(100):
    loss = loss_func(qlayer.params)
    print(loss)
    loss.backward()
    optimQNG.step()
    optimQNG.zero_grad()


import math
import torch
import torch.nn as nn
import torch.optim as optim
from torch.autograd import Variable
import numpy as np
import torchvision
import matplotlib.pyplot as plt
import time
import copy
import os
import pdb
import shutil
from torch.utils.data import DataLoader
from torchvision import datasets, models, transforms

import utilities.utils as utils

class Elastic_SGD(optim.SGD):
    def __init__(self, params, lr=0.001, momentum=0, dampening=0,
                 weight_decay=0, nesterov=False):
        super(Elastic_SGD, self).__init__(params, lr, momentum, dampening, weight_decay, nesterov)

    def __setstate__(self, state):
        super(Elastic_SGD, self).__setstate__(state)

    def step(self, reg_params, closure=None):
        """Performs a single optimization step.
        Arguments:
            closure (callable, optional): A closure that reevaluates the model
                and returns the loss.
        """

        # print('************************DOING A STEP************************')
        # loss=super(Elastic_SGD, self).step(closure)
        loss = None
        if closure is not None:
            loss = closure()
        index = 0
        reg_lambda = reg_params.get('lambda')
        for group in self.param_groups:
            weight_decay = group['weight_decay']
            momentum = group['momentum']
            dampening = group['dampening']
            nesterov = group['nesterov']

            for p in group['params']:
                # print('************************ONE PARAM************************')

                if p.grad is None:
                    continue

                d_p = p.grad.data
                unreg_dp = p.grad.data.clone()
                # HERE MY CODE GOES
                reg_param = reg_params.get(p)

                omega = reg_param.get('omega')
                zero = torch.FloatTensor(p.data.size()).zero_()
                init_val = reg_param.get('init_val')
                w = reg_param.get('w')
                curr_wegiht_val = p.data.clone()
                # move the variables to cuda
                init_val = init_val.cuda()
                w = w.cuda()
                omega = omega.cuda()
                # get the difference
                weight_dif = curr_wegiht_val.add(-1, init_val)

                regulizer = torch.mul(weight_dif, 2 * reg_lambda * omega)
                # JUST NOW PUT BACK
                d_p.add_(regulizer)

                del weight_dif
                del omega

                del regulizer
                # HERE MY CODE ENDS

                if weight_decay != 0:
                    d_p.add_(weight_decay, p.data)

                if momentum != 0:
                    # pdb.set_trace()
                    param_state = self.state[p]
                    if 'momentum_buffer' not in param_state:
                        buf = param_state['momentum_buffer'] = d_p.clone()
                    else:
                        buf = param_state['momentum_buffer']
                        buf.mul_(momentum).add_(1 - dampening, d_p)
                    if nesterov:
                        d_p = d_p.add(momentum, buf)
                    else:
                        d_p = buf
                #
                p.data.add_(-group['lr'], d_p)
                w_diff = p.data.add(-1, curr_wegiht_val)

                del curr_wegiht_val

                change = w_diff.mul(unreg_dp)
                del unreg_dp
                change = torch.mul(change, -1)
                del w_diff
                if 0:
                    if change.equal(zero.cuda()):
                        print('change zero')
                        pdb.set_trace()
                    if w.equal(zero.cuda()):
                        print('w zero')

                    if w.equal(zero.cuda()):
                        print('w after zero')
                    x = p.data.add(-init_val)
                    if x.equal(zero.cuda()):
                        print('path diff is zero')
                del zero
                del init_val
                w.add_(change)
                reg_param['w'] = w
                # after deadline

                reg_params[p] = reg_param
                index += 1
        return loss

def set_lr(optimizer, lr, count):
    """Decay learning rate by a factor of 0.1 every lr_decay_epoch epochs."""
    continue_training = True
    if count >= 10:
        continue_training = False
        print("training terminated")
    if count == 5:
        lr = lr * 0.1
        print('lr is set to {}'.format(lr))
        for param_group in optimizer.param_groups:
            param_group['lr'] = lr

    return optimizer, lr, continue_training

def traminate_protocol(since, best_acc):
    time_elapsed = time.time() - since
    print('Training complete in {:.0f}m {:.0f}s'.format(
        time_elapsed // 60, time_elapsed % 60))
    utils.print_timing(time_elapsed, "TRAINING ONLY")
    print('Best val Acc: {:4f}'.format(best_acc))

def train_model(model, criterion, optimizer, lr, dset_loaders, dset_sizes, use_gpu, num_epochs, exp_dir='./',
                resume='', saving_freq=5):
    print('dictoinary length' + str(len(dset_loaders)))
    since = time.time()
    val_beat_counts = 0  # number of time val accuracy not imporved
    best_model = model
    best_acc = 0.0
    mem_snapshotted = False

    if os.path.isfile(resume):

        print("=> loading checkpoint '{}'".format(resume))
        checkpoint = torch.load(resume)
        start_epoch = checkpoint['epoch']
        best_acc = checkpoint['best_acc']
        model.load_state_dict(checkpoint['state_dict'])
        lr = checkpoint['lr']
        print("lr is ", lr)
        val_beat_counts = checkpoint['val_beat_counts']
        print("val_beat_counts", val_beat_counts)
        print('load')
        optimizer.load_state_dict(checkpoint['optimizer'])
        print("=> loaded checkpoint '{}' (epoch {})"
              .format(resume, checkpoint['epoch']))
    else:
        start_epoch = 0
        print("=> no checkpoint found at '{}'".format(resume))

    warning_NAN_counter = 0
    print("START EPOCH = ", str(start_epoch))
    for epoch in range(start_epoch, num_epochs + 1):
        print('Epoch {}/{}'.format(epoch, num_epochs))
        print('-' * 10)

        # Each epoch has a training and validation phase
        for phase in ['train', 'val']:
            if phase == 'train':
                optimizer, lr, continue_training = set_lr(optimizer, lr, count=val_beat_counts)
                if not continue_training:
                    traminate_protocol(since, best_acc)
                    return model, best_acc
                model.train(True)  # Set model to training mode
            else:
                model.train(False)  # Set model to evaluate mode

            running_loss = 0.0
            running_corrects = 0

            # Iterate over data.
            for data in dset_loaders[phase]:
                # get the inputs
                inputs, labels = data

                # wrap them in Variable
                if use_gpu:
                    inputs, labels = Variable(inputs.cuda()), \
                                     Variable(labels.cuda())
                else:
                    inputs, labels = Variable(inputs), Variable(labels)

                # zero the parameter gradients
                optimizer.zero_grad()
                model.zero_grad()
                # forward
                outputs = model(inputs)
                _, preds = torch.max(outputs.data, 1)
                loss = criterion(outputs, labels)

                # backward + optimize only if in training phase
                if phase == 'train':
                    loss.backward()
                    # print('step')
                    optimizer.step(model.reg_params)

                # statistics
                if not math.isnan(loss.data.item()):
                    warning_NAN_counter += 1

                if not mem_snapshotted:
                    utils.save_cuda_mem_req(exp_dir)
                    mem_snapshotted = True

                running_loss += loss.data.item()
                running_corrects += torch.sum(preds == labels.data).item()

            epoch_loss = running_loss / dset_sizes[phase]

            if warning_NAN_counter > 0:
                print("SKIPPED NAN RUNNING LOSS FOR BATCH: ", warning_NAN_counter, " TIMES")
            print("EPOCH LOSS=", epoch_loss, ", RUNNING LOSS=", running_loss, ",DIVISION=", dset_sizes[phase])
            if epoch_loss > 1e4 or math.isnan(epoch_loss):
                print("TERMINATING: Epoch loss [", epoch_loss, "]  is NaN or > 1e4")
                return model, best_acc
            epoch_acc = running_corrects / dset_sizes[phase]

            print('{} Loss: {:.4f} Acc: {:.4f}'.format(
                phase, epoch_loss, epoch_acc))

            # deep copy the model
            if phase == 'val':
                if epoch_acc > best_acc:
                    del outputs
                    del labels
                    del inputs
                    del loss
                    del preds
                    best_acc = epoch_acc
                    torch.save(model, os.path.join(exp_dir, 'best_model.pth.tar'))
                    val_beat_counts = 0
                else:
                    val_beat_counts += 1

        if epoch % saving_freq == 0:
            epoch_file_name = exp_dir + '/' + 'epoch' + '.pth.tar'
            save_checkpoint({
                'epoch_acc': epoch_acc,
                'best_acc': best_acc,
                'epoch': epoch + 1,
                'lr': lr,
                'val_beat_counts': val_beat_counts,
                'arch': 'alexnet',
                'model': model,
                'state_dict': model.state_dict(),
                'optimizer': optimizer.state_dict(),
            }, epoch_file_name)
        print()

    time_elapsed = time.time() - since
    print('Training complete in {:.0f}m {:.0f}s'.format(
        time_elapsed // 60, time_elapsed % 60))
    print('Best val Acc: {:4f}'.format(best_acc))
    return model, best_acc  # initialize importance dictionary

def initialize_reg_params(model):
    reg_params = {}
    for name, param in model.named_parameters():  # after deadline check
        w = torch.FloatTensor(param.size()).zero_()
        omega = torch.FloatTensor(param.size()).zero_()
        init_val = param.data.clone()
        reg_param = {}
        reg_param['omega'] = omega
        reg_param['w'] = w
        reg_param['init_val'] = init_val
        reg_param['name'] = name
        reg_params[param] = reg_param
    return reg_params

def update_reg_params(model, slak=1e-3):
    reg_params = model.reg_params
    index = 0
    for param in list(model.parameters()):
        print('index' + str(index))
        if param in reg_params.keys():
            print('updating index' + str(index))
            reg_param = reg_params.get(param)
            w = reg_param.get('w').cuda()
            zero = torch.FloatTensor(param.data.size()).zero_()

            if w.equal(zero.cuda()):
                print('W IS WRONG WARNING')
            omega = reg_param.get('omega')
            omega = omega.cuda()
            if not omega.equal(zero.cuda()):
                print('omega is not equal zero')
            else:
                print('omega is equal zero')

            omega = omega.cuda()
            init_val = reg_param.get('init_val')
            init_val = init_val.cuda()
            path_diff = param.data.add(-1, init_val)
            if path_diff.equal(zero.cuda()):
                print('PATH DIFF WRONG WARNING')
            dominator = path_diff.pow(2)
            dominator.add_(slak)
            this_omega = w.div(dominator)

            ####
            if 0:
                the_size = 1
                for x in this_omega.size():
                    the_size = the_size * x
                om = this_omega.view(the_size)
                randindex = torch.randperm(the_size)
                om = om[randindex.cuda()]
                this_omega = om.view(this_omega.size())

            this_omega = torch.max(this_omega, zero.cuda())
            print("**********max*************")
            print(this_omega.max())
            print("**********min*************")
            print(this_omega.min())
            omega.add_(this_omega)

            reg_param['omega'] = omega
            w = zero.cuda()
            reg_param['w'] = w
            reg_param['init_val'] = param.data.clone()
            reg_params[param] = reg_param
        else:
            print('initializing index' + str(index))
            w = torch.FloatTensor(param.size()).zero_()
            omega = torch.FloatTensor(param.size()).zero_()
            init_val = param.data.clone()
            reg_param = {}
            reg_param['omega'] = omega
            reg_param['w'] = w
            reg_param['init_val'] = init_val
            reg_params[param] = reg_param
        index = index + 1
    return reg_params

def update_reg_params(model, slak=1e-3):
    reg_params = model.reg_params
    index = 0
    for param in list(model.parameters()):
        print('index' + str(index))
        if param in reg_params.keys():
            print('updating index' + str(index))
            reg_param = reg_params.get(param)
            w = reg_param.get('w').cuda()
            zero = torch.FloatTensor(param.data.size()).zero_()

            if w.equal(zero.cuda()):
                print('W IS WRONG WARNING')
            omega = reg_param.get('omega')
            omega = omega.cuda()
            if not omega.equal(zero.cuda()):
                print('omega is not equal zero')
            else:
                print('omega is equal zero')

            omega = omega.cuda()
            init_val = reg_param.get('init_val')
            init_val = init_val.cuda()
            path_diff = param.data.add(-1, init_val)
            if path_diff.equal(zero.cuda()):
                print('PATH DIFF WRONG WARNING')
            dominator = path_diff.pow(2)
            dominator.add_(slak)
            this_omega = w.div(dominator)

            ####
            if 0:
                the_size = 1
                for x in this_omega.size():
                    the_size = the_size * x
                om = this_omega.view(the_size)
                randindex = torch.randperm(the_size)
                om = om[randindex.cuda()]
                this_omega = om.view(this_omega.size())

            this_omega = torch.max(this_omega, zero.cuda())
            print("**********max*************")
            print(this_omega.max())
            print("**********min*************")
            print(this_omega.min())
            omega.add_(this_omega)

            reg_param['omega'] = omega
            w = zero.cuda()
            reg_param['w'] = w
            reg_param['init_val'] = param.data.clone()
            reg_params[param] = reg_param
        else:
            print('initializing index' + str(index))
            w = torch.FloatTensor(param.size()).zero_()
            omega = torch.FloatTensor(param.size()).zero_()
            init_val = param.data.clone()
            reg_param = {}
            reg_param['omega'] = omega
            reg_param['w'] = w
            reg_param['init_val'] = init_val
            reg_params[param] = reg_param
        index = index + 1
    return reg_params

def update_reg_params_ref(model, slak=1e-3):
    reg_params = model.reg_params
    new_reg_params = {}
    index = 0
    for param in list(model.parameters()):
        print('index' + str(index))

        reg_param = reg_params.get(param)
        w = reg_param.get('w')
        zero = torch.FloatTensor(param.data.size()).zero_()
        if w.equal(zero.cuda()):
            print('wrong')
        omega = reg_param.get('omega')
        omega = omega.cuda()
        if not omega.equal(zero.cuda()):
            print('omega wrong')

        omega = omega.cuda()
        init_val = reg_param.get('init_val')
        init_val = init_val.cuda()
        path_diff = param.data.add(-init_val)
        if path_diff.equal(zero.cuda()):
            print('path_diff wrong')
        dominator = path_diff.pow_(2)
        dominator.add_(slak)
        this_omega = w.div(dominator)
        if this_omega.equal(zero.cuda()):
            print('this_omega wrong')
        omega.add_(this_omega)
        reg_param['omega'] = omega
        reg_param['w'] = w
        reg_param['init_val'] = param.data
        reg_params[param] = reg_param
        model.reg_params = reg_params
        new_reg_params[index] = reg_param
        index = index + 1
    return new_reg_params

def reassign_reg_params(model, new_reg_params):
    reg_params = model.reg_params
    reg_params = {}
    index = 0
    for param in list(model.parameters()):
        reg_param = new_reg_params[index]
        reg_params[param] = reg_param
        index = index + 1
    model.reg_params = reg_params
    return reg_params

def save_checkpoint(state, filename='checkpoint.pth.tar'):
    torch.save(state, filename)


import copy
import itertools
from hyperopt.genson_helpers import (null,
                         false,
                         true,
                         choice,
                         uniform,
                         gaussian,
                         lognormal,
                         qlognormal,
                         ref)

lnorm = {'kwargs':{'inker_shape' : choice([(3,3),(5,5),(7,7),(9,9)]),
         'outker_shape' : ref('this','inker_shape'),
         'remove_mean' : choice([0,1]),
         'stretch' : uniform(0,10),
         'threshold' : choice([null, uniform(0,10)])
         }}

lpool = {'kwargs': {'ker_shape' : choice([(3,3),(5,5),(7,7),(9,9)]),
          'order' : choice([1, 2, 10])
         }}

rescale = {'kwargs': {'stride' : 2}}

activ =  {'kwargs': {'min_out' : choice([null, 0]),
                     'max_out' : choice([1, null])}}

filter1 = dict(
         initialize=dict(
            filter_shape=choice([(3,3),(5,5),(7,7),(9,9)]),
            n_filters=choice([16, 32, 64]),
            generate=(
                'random:uniform',
                {'rseed': choice(range(5))})),
         kwargs={})

filter2 = copy.deepcopy(filter1)
filter2['initialize']['n_filters'] = choice([16, 32, 64, 128])
filter2['initialize']['generate'] = ('random:uniform', {'rseed': choice(range(5,10))})

filter3 = copy.deepcopy(filter1)
filter3['initialize']['n_filters'] = choice([16, 32, 64, 128, 256])
filter3['initialize']['generate'] = ('random:uniform', {'rseed': choice(range(10,15))})

#################
###original model
original_params = {'desc': [[('lnorm', lnorm)],
            [('fbcorr', filter1),
             ('activ', activ),
             ('lpool', lpool),
             ('rescale', rescale),
             ('lnorm', lnorm)],
            [('fbcorr', filter2),
             ('activ', activ),
             ('lpool', lpool),
             ('rescale', rescale),
             ('lnorm', lnorm)],
            [('fbcorr', filter3),
             ('activ', activ),
             ('lpool', lpool),
             ('rescale', rescale),
             ('lnorm', lnorm)],
           ]}

####################
####reordered models
order_choices = [[list(_o[:_ind]),list(_o[_ind:])] for _o in list(itertools.permutations(['lpool','activ','lnorm'])) for _ind in range(4)]
orders = choice(order_choices)

values = [{'lnorm':lnorm, 'lpool':lpool, 'activ':activ, 'filter':filter1},
          {'lnorm':lnorm, 'lpool':lpool, 'activ':activ, 'filter':filter2},
          {'lnorm':lnorm, 'lpool':lpool, 'activ':activ, 'filter':filter3}]
value_params = {'values': values}
order_value_params = {'order':orders, 'values':values}

order_value_params_other = copy.deepcopy(order_value_params)
order_value_params_other['preproc'] = {'size': choice([
                                                       #(150, 150),
                                                       (250, 250)
                                                      ]),
                                       'global_normalize': false}

values2 = [{'lnorm':lnorm, 'lpool':lpool, 'activ':activ, 'filter':filter1},
           {'lnorm':lnorm, 'lpool':lpool, 'activ':activ, 'filter':filter2}]
order_value_params2 = {'order':orders, 'values':values2}

basic = ['lpool','activ','lnorm']
order_choices_single_removals_base = [[[list(_o[:_ind]),list(_o[_ind:])] for _o in list(itertools.permutations(_sset)) for _ind in range(len(_sset)+1)] for _sset in itertools.combinations(basic, 2)]
order_choices_single_removals = list(itertools.chain(*order_choices_single_removals_base))
order_choices_double_removals_base = [[[list(_o[:_ind]),list(_o[_ind:])] for _o in list(itertools.permutations(_sset)) for _ind in range(len(_sset)+1)] for _sset in itertools.combinations(basic, 1)]
order_choices_double_removals = list(itertools.chain(*order_choices_double_removals_base))
order_choices_removals = order_choices_single_removals + order_choices_double_removals

def get_relevant_values(_v, _ord):
    ops = _ord[0] + _ord[1] + ['filter']
    _v = copy.deepcopy(_v)
    for (_ind, _vd) in enumerate(_v):
        _v[_ind] = dict([(key,val) for (key,val) in _v[_ind].items() if key in ops])
    return _v

order_choices_removals_values = [{'order':_o, 'values': get_relevant_values(values, _o)} for _o in order_choices_removals]
order_removals_value_params = {'desc': choice(order_choices_removals_values)}

order_choices_removals_values_other = [{'order':_o,
                                        'values': get_relevant_values(values, _o),
                                        'preproc': {'size': choice([
                                                                     #(150, 150),
                                                                     (250, 250)
                                                                    ]),
                                                    'global_normalize': false}
                                        } for _o in order_choices_removals]
order_removals_value_params_other = {'desc': choice(order_choices_removals_values_other)}

def get_reordered_model_config(config):
    if 'desc' in config:
        config = config['desc']
    before, after = config['order']
    values = config['values']
    layers = []
    newconfig = {'desc':layers}
    for (layer_ind, vals) in enumerate(values):
        B = [(b, vals[b]) for b in before]
        A = [(a, vals[a]) for a in after]
        layer = B + [('fbcorr',vals['filter'])] + A + [('rescale',rescale)]
        layers.append(layer)
    if 'preproc' in config:
        newconfig['preproc'] = config['preproc']
    return newconfig

def remove(s,s0):
    s = s[:]
    for s0e in s0:
        s.remove(s0e)
    return s
standard_order = ['activ', 'lpool', 'lnorm']
standard_removed_orders_first = [([[], remove(standard_order,k)], [[],standard_order]) for k in itertools.chain(itertools.combinations(standard_order, 2), itertools.combinations(standard_order, 1))]
standard_removed_orders_last = [([[],standard_order], [[], remove(standard_order,k)]) for k in itertools.chain(itertools.combinations(standard_order, 2), itertools.combinations(standard_order, 1))]
standard_removed_orders_first_different = standard_removed_orders_first + standard_removed_orders_last

def get_relevant_values_first_different(_v, _ord):
    _v = copy.deepcopy(_v)
    for (_ind, _vd) in enumerate(_v):
        o_ind = 0 if _ind == 0 else 1
        ops = _ord[o_ind][0] + _ord[o_ind][1] + ['filter']
        _v[_ind] = dict([(key,val) for (key,val) in _v[_ind].items() if key in ops])
    return _v

standard_removed_orders_first_different_values = [{'order':_o, 'values': get_relevant_values_first_different(values,_o)} for _o in standard_removed_orders_first_different]
standard_order_removals_first_different_value_params = {'desc': choice(standard_removed_orders_first_different_values)}

def get_reordered_model_config_first_different(config):
    if 'desc' in config:
        config = config['desc']
    values = config['values']
    layers = []
    newconfig = {'desc':layers}
    for (layer_ind, vals) in enumerate(values):
        before, after = config['order'][0 if layer_ind == 0 else 1]
        B = [(b, vals[b]) for b in before]
        A = [(a, vals[a]) for a in after]
        layer = B + [('fbcorr',vals['filter'])] + A + [('rescale',rescale)]
        layers.append(layer)
    return newconfig

fg11_top_params = {'desc':[[('lnorm',{'kwargs':{'inker_shape': (9, 9),
                     'outker_shape': (9, 9),
                     'stretch':10,
                     'threshold': 1}})],
         [('fbcorr', {'initialize': {'filter_shape': (3, 3),
                                     'n_filters': 64,
                                     'generate': ('random:uniform',
                                                  {'rseed': choice(range(5))})},
                      'kwargs':{}}),
          ('activ', {'min_out': 0,
                     'max_out': null}),
          ('lpool', {'kwargs': {'ker_shape': (7, 7),
                                'order': 1}}),
          ('rescale', rescale),
          ('lnorm', {'kwargs': {'inker_shape': (5, 5),
                                'outker_shape': (5, 5),
                                'stretch': 0.1,
                                'threshold': 1}})],
         [('fbcorr', {'initialize': {'filter_shape': (5, 5),
                                     'n_filters': 128,
                                     'generate': ('random:uniform',
                                                  {'rseed': choice(range(5))})},
                      'kwargs': {}}),
          ('activ', {'min_out': 0,
                     'max_out': null}),
          ('lpool', {'kwargs': {'ker_shape': (5, 5),
                                'order': 1}}),
          ('rescale', rescale),
          ('lnorm', {'kwargs': {'inker_shape': (7, 7),
                                'outker_shape': (7, 7),
                                'stretch': 1,
                                'threshold': 1}})],
         [('fbcorr', {'initialize': {'filter_shape': (5, 5),
                                     'n_filters': 256,
                                     'generate': ('random:uniform',
                                                 {'rseed': choice(range(5))})},
                      'kwargs': {}}),
           ('activ', {'min_out': 0,
                      'max_out': null}),
           ('lpool', {'kwargs': {'ker_shape': (7, 7),
                                 'order': 10}}),
           ('rescale', rescale),
           ('lnorm', {'kwargs': {'inker_shape': (3, 3),
                                 'outker_shape': (3, 3),
                                 'stretch': 10,
                                 'threshold': 1}})]]}

cvpr_top_params = {'desc':[[('lnorm',
       {'kwargs': {'inker_shape': [5, 5],
         'outker_shape': [5, 5],
         'remove_mean': 0,
         'stretch': 0.1,
         'threshold': 1}})],
     [('fbcorr',
       {'initialize': {'filter_shape': [5, 5],
         'generate': ['random:uniform', {'rseed': 12}],
         'n_filters': 64},
        'kwargs': {}}),
      ('activ', {'kwargs': {'max_out': null, 'min_out': 0}}),
      ('lpool', {'kwargs': {'ker_shape': [7, 7], 'order': 10}}),
      ('rescale', rescale),
      ('lnorm',
       {'kwargs': {'inker_shape': [5, 5],
         'outker_shape': [5, 5],
         'remove_mean': 1,
         'stretch': 0.1,
         'threshold': 10}})],
     [('fbcorr',
       {'initialize': {'filter_shape': [7, 7],
         'generate': ['random:uniform', {'rseed': 24}],
         'n_filters': 64},
        'kwargs': {}}),
      ('activ', {'kwargs': {'max_out': null, 'min_out': 0}}),
      ('lpool', {'kwargs': {'ker_shape': [3, 3], 'order': 1}}),
      ('rescale', rescale),
      ('lnorm',
       {'kwargs': {'inker_shape': [3, 3],
         'outker_shape': [3, 3],
         'remove_mean': 1,
         'stretch': 1,
         'threshold': 0.1}})],
     [('fbcorr',
       {'initialize': {'filter_shape': [3, 3],
         'generate': ['random:uniform', {'rseed': 32}],
         'n_filters': 256},
        'kwargs': {}}),
      ('activ', {'kwargs':{'max_out': null, 'min_out': null}}),
      ('lpool', {'kwargs': {'ker_shape': [3, 3], 'order': 2}}),
      ('rescale', rescale),
      ('lnorm',
       {'kwargs': {'inker_shape': [3, 3],
         'outker_shape': [3, 3],
         'remove_mean': 1,
         'stretch': 0.1,
         'threshold': 1}})]]}

def trans_fn(x):
    tdict = {'a': 'activ', 'p': 'lpool', 'n': 'lnorm'}
    ord = [[]]
    cur = 0
    for y in x:
        if y == '|':
            cur += 1
            ord.append([])
        else:
            ord[cur].append(tdict[y])
    return ord

ap_values = [{'lpool':lpool, 'activ':activ, 'filter':filter1},
             {'lpool':lpool, 'activ':activ, 'filter':filter2},
             {'lpool':lpool, 'activ':activ, 'filter':filter3}]

good_order_abbrevs = ['|ap', 'p|a', 'ap|']
good_orders = map(trans_fn, good_order_abbrevs)
good_order_value_params = {'desc': {'order': choice(good_orders),
                                    'values': ap_values,
                                    'preproc':{'size': [200, 200],
                                    'global_normalize': choice([0, 1])}
                                    }}

good_order_abbrevs2 = ['|apn', '|anp', '|nap']
good_orders2 = map(trans_fn, good_order_abbrevs2)
good_order_value_params2 = {'desc': {'order': choice(good_orders2),
                                     'values': values,
                                     'preproc':{'size': [200, 200],
                                     'global_normalize': choice([0, 1])}
                                     }}


num = int(input('Enter a Number: '))

def nPowers(n):
    if n<1:
        return 0
    elif n==1:
        return n
    else:
        prev= nPowers(n//2)
        print(f"previous: {prev}")
        curr= prev*2
        print(f"current: {curr}")
    return curr

print('Output:',nPowers(num))


#!/usr/bin/env python

import os
import unittest
import logging

from flask import Flask

from tests.flask_oauthlib_api_spec import FlaskOAuthlibSpecs
from models import (db, Consumer, ConsumerUserAccess, User,
        RequestToken, Nonce, create_app)

log = logging.getLogger(__name__)

CONSUMER_KEY = '123456789012345678901234567890'
CONSUMER_SECRET = '1234567890123456789012345678901234567890'
REQUEST_TOKEN = '123456789012345678901234567890'
REQUEST_TOKEN_SECRET = '1234567890123456789012345678901234567890'
ACCESS_TOKEN = '123456789012345678901234567890'
ACCESS_TOKEN_SECRET = '1234567890123456789012345678901234567890'
TIMESTAMP = 1442305580
NONCE = '1234567890123456789012345678901234567890'
REALM = 'read'
USERNAME = "Mike O'Sullivan"
REDIRECT_URI = 'http://localhost:8000/callback'

app = create_app()

class ModelsTest(unittest.TestCase):

    def setUp(self):
        log.debug("Create tables.")
        with app.app_context():
            db.create_all()
        self.assertEqual([], Consumer.query.all())
        self.assertEqual([], ConsumerUserAccess.query.all())
        log.debug("Tables created.")

        # Test insert; also sets up for other tests.
        u = User(name="Mike O'Sullivan")
        c = Consumer(
            creator=u,
            client_key='my-key',
            client_secret='my-secret',
            redirect_uris=['http://localhost:8000/callback'],
            realms=['read'])
        self.assertEqual([], Consumer.query.all())
        db.session.add(u)
        db.session.add(c)
        self.assertEqual([c], Consumer.query.all())  # Volatile!
        db.session.commit()
        self.assertEqual([c], Consumer.query.all())  # Persisted.

    def test_select(self):
        consumers = Consumer.query.all()
        self.assertEqual(1, len(consumers))
        c = consumers[0]
        self.assertEqual('my-key', c.client_key)
        self.assertEqual('my-secret', c.client_secret)

    def test_update(self):
        c = Consumer.query.one()
        c.client_key = 'new-key'
        another_ref = Consumer.query.one()
        self.assertEqual('new-key', another_ref.client_key)  # Volatile?
        db.session.commit()  # Persisted.

    def test_delete(self):
        c = Consumer.query.one()
        db.session.delete(c)
        self.assertEqual([], Consumer.query.all())  # Volatile?
        db.session.commit()
        self.assertEqual([], Consumer.query.all())  # Persisted.

    def test_relationships(self):
        c = Consumer.query.one()
        u = User.query.one()
        self.assertTrue(u.name.startswith("Mike"))
        cua = ConsumerUserAccess(
            client=c,
            user=u,
            realms=['read'],
            token='CU-AT',
            secret='CU-ATS')
        self.assertEqual([cua], c.accesses_to_users.all())
        self.assertEqual([cua], u.accesses_from_consumers.all())
        # Persist
        db.session.add(cua)
        db.session.commit()
        self.assertEqual([cua], Consumer.query.one().accesses_to_users.all())
        self.assertEqual([cua], User.query.one().accesses_from_consumers.all())

    def tearDown(self):
        log.debug("Drop tables.")

        # Otherwise hangs at drop_all.
        # More info: http://stackoverflow.com/questions/24289808/
        db.session.commit()

        with app.app_context():
            db.drop_all()
        log.debug("Tables dropped.")

class FlaskOAuthlibModelsSpecTest(unittest.TestCase, FlaskOAuthlibSpecs):

    def setUp(self):
        self.user = User(name=USERNAME)
        self.consumer = Consumer(
            creator=self.user,
            client_key=CONSUMER_KEY, # 30 chars
            client_secret=CONSUMER_SECRET,
            redirect_uris=[REDIRECT_URI],
            realms=[REALM])
        self.request_token = RequestToken(
            client=self.consumer,
            token=REQUEST_TOKEN,
            secret=REQUEST_TOKEN_SECRET,
            realms=[REALM],
            redirect_uri=REDIRECT_URI,
            user=self.user)
        self.nonce = Nonce(
            client_key=CONSUMER_KEY,
            timestamp=TIMESTAMP,
            nonce=NONCE,
            request_token=REQUEST_TOKEN,
            access_token=ACCESS_TOKEN)
        self.access_token = ConsumerUserAccess(
            client=self.consumer,
            user=self.user,
            realms=[REALM],
            token=ACCESS_TOKEN,
            secret=ACCESS_TOKEN_SECRET)

    def test_types(self):
        self.api_test_client(self.consumer)
        self.api_test_request_token(self.request_token, User, Consumer)
        self.api_test_access_token(self.access_token, User, Consumer)
        self.api_test_nonce(self.nonce)

if __name__ == '__main__':
    uri = os.getenv('SQLALCHEMY_TESTING_DATABASE_URI')
    print('=' * 80)
    print('  WARNING: You may be about to drop your production database!')
    print('  Database URI in use for testing: {}'.format(uri))
    print('=' * 80)
    try:
        input('Press ^C to cancel, or <Enter> to continue')
    except KeyboardInterrupt:
        os.exit()
    app.config['SQLALCHEMY_DATABASE_URI'] = uri
    with app.app_context():
        unittest.main()


import xml.etree.ElementTree as ET
from pathlib import Path
import re
from collections import defaultdict

ET.register_namespace('', 'http://www.w3.org/2000/svg')
sprite = ET.XML('<svg><defs/></svg>')
defs = sprite.find('defs')

ids = {}
for svg in Path('.').glob('photon-icons/icons/desktop/*.svg'):
    id = re.sub(r'-\d+', '', svg.stem)
    if id in ids:
        continue
    ids[id] = True

    symbol = ET.parse(svg).getroot()
    symbol.tag = 'symbol'
    symbol.set('id', id)
    del symbol.attrib['height']
    del symbol.attrib['width']

    has_context_fill = False
    for element in symbol.findall('*') + [symbol]:
        for attr in ['fill', 'stroke']:
            if element.get(attr) is not None:
                if 'context-fill' in element.get(attr):
                    has_context_fill = True
                element.set(attr, element.get(attr).replace('context-fill', 'currentColor'))
        if element.get('fill-opacity') is not None:
            element.set('fill-opacity', element.get('fill-opacity').replace('context-fill-opacity', ''))

    if not has_context_fill:
        for element in symbol.findall('*'):
            try:
                del element.attrib['fill']
            except KeyError:
                pass
        symbol.set('fill', 'currentColor')

    defs.append(symbol)

comment = ET.Comment('''
    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.
''')
sprite.insert(0, comment)

Path('dist').mkdir(exist_ok=True)
ET.ElementTree(element=sprite).write('dist/photon-icons.svg',
                                     encoding='utf-8', xml_declaration=True)


# -- coding: utf-8 --
# @Time : 2022/7/21
# @Author : ykk648
# @Project : https://github.com/ykk648/AI_power
import numpy as np
from cv2box import CVImage, MyFpsCounter, CVBbox

from apstone import ONNXModel
from body_lib.body_kp_detector.blazepose_mediapipe.blaze_utils import postprocess, denormalize_landmarks, detection2roi, \
    extract_roi
from body_lib.body_bbox_detector import BodyBboxDetector

# input 1*256*256*3 output , 1*1 , , ,
LITE_MODEL = 'pretrain_models/body_lib/body_kp_detector/blazepose_mediapipe/pose_landmark_lite.onnx'
FULL_MODEL = 'pretrain_models/body_lib/body_kp_detector/blazepose_mediapipe/pose_landmark_full.onnx'
HEAVY_MODEL = 'pretrain_models/body_lib/body_kp_detector/blazepose_mediapipe/pose_landmark_heavy.onnx'

class LandmarkDetectorYolox:
    def __init__(self, model_complexity=0, provider='gpu'):
        self.bbd = BodyBboxDetector(model='yolox_tiny_trt16', threshold=0.5)

        model_path_list = [LITE_MODEL, FULL_MODEL, HEAVY_MODEL]
        self.model = ONNXModel(model_path_list[model_complexity], provider=provider)

        self.need_bbox_flag = True
        self.history = []

    def forward(self, image_in_, show=False):
        """

        Args:
            image_in_:
            show:
        Returns:
            landmarks: 33*4

        """
        bbox_result = self.bbd.forward(image_in_, show=False, max_bbox_num=1)[0]
        img, ratio, left, top = CVImage(image_in_).crop_keep_ratio(bbox_result, (256, 256), padding_ratio=1.)

        if show:
            CVImage(img).show(0, 'img_crop')

        blob = (img / 256).astype(np.float32)[np.newaxis, :]
        normalized_landmarks, f, ee, rr, tt = self.model.forward(blob)
        normalized_landmarks = postprocess(normalized_landmarks)[0]
        landmarks_ = CVImage(None).recover_from_crop(normalized_landmarks, ratio, left, top, (256, 256))

        if show:
            show_img = CVImage(image_in_).draw_landmarks(landmarks_)
            CVImage(show_img).show(0, 'results')
        return landmarks_

    def forward_w_tracking(self, image_in_, show=False):
        if self.need_bbox_flag:
            bbox_result = self.bbd.forward(image_in_, show=False, max_bbox_num=1)[0]
        else:
            reserve_points = [0, 7, 8, 11, 12, 23, 24, 25, 26, 27, 28]
            bbox_result = CVBbox(None).get_bbox_from_points(self.history[-1][reserve_points], image_in_.shape,
                                                            margin_ratio=0.2)

        img, ratio, left, top = CVImage(image_in_).crop_keep_ratio(bbox_result, (256, 256), padding_ratio=1.)

        if show:
            CVImage(img).show(0, 'img_crop')

        blob = (img / 256).astype(np.float32)[np.newaxis, :]
        normalized_landmarks, f, _, _, _ = self.model.forward(blob)
        normalized_landmarks = postprocess(normalized_landmarks)[0]
        landmarks_ = CVImage(None).recover_from_crop(normalized_landmarks, ratio, left, top, (256, 256))

        self.need_bbox_flag = False
        self.history.append(landmarks_)
        self.history = self.history[-2:]

        if show:
            show_img = CVImage(image_in_).draw_landmarks(landmarks_)
            CVImage(show_img).show(0, 'results')
        return landmarks_

if __name__ == '__main__':
    # image_path = 'resources/for_pose/t_pose_1080p.jpeg'
    # image_in = CVImage(image_path).bgr

    """
    model 1 82fps trt16  trt 109fps
    model 2 67fps trt16 output Nan trt 97fps
    """
    ld = LandmarkDetectorYolox(model_complexity=2, provider='trt')

    # landmarks = ld.forward(image_in, show=True)
    # print(landmarks)
    #
    # with MyFpsCounter('model forward 10 times fps: ') as mfc:
    #     for i in range(10):
    #         filtered_detections = ld.forward(image_in)

    # video tracking test
    from cv2box import CVVideoLoader
    from tqdm import tqdm

    with CVVideoLoader('') as cvvl:
        for _ in tqdm(range(len(cvvl))):
            _, frame = cvvl.get()
            landmarks = ld.forward_w_tracking(frame, show=False)


"""
选择排序：
1. 首先，找到数组中最小的元素，将其与数组中第一个元素进行交换（如果第一个元素就是最小的元素那么它就自己和自己换）
2. 其次，在剩下的元素中找到最小的元素，将其与数组中第二个元素进行交换，以此类推

复杂度：
1. 时间复杂度：最多需要进行(N^2)/2 比较, 即O(N^2)
2. 空间复杂度：O(1)
"""

def selectionSort(nums):
    n = len(nums)
    if n <= 1: return
    for i in range(0, n):
        # 初始化当前最小值的索引
        min = i
        for j in range(i+1, n):
            # 从前往后开始遍历，如果遇到比当前值更小的值
            # 更新索引
            if nums[j] < nums[min]: min = j
        # 把找到的最小值与当前值做交换
        nums[i], nums[min] = nums[min], nums[i]

nums = [5,2,6,4,3,1,8,7]
print(f"Original array: {nums}")
selectionSort(nums)
print(f"Sorted array: {nums}")


class Solution:
    def isPalindrome(self, word: str) -> bool:
        i, j = 0, len(word) - 1
        while i < j:
            if word[i] != word[j]:
                return False
            i += 1
            j -= 1
        return True

    def firstPalindrome(self, words: List[str]) -> str:
        for word in words:
            if self.isPalindrome(word):
                return word
        return ''


from collections import OrderedDict

def checkio(whole):
    roman_number = ""
    roman_symbols = OrderedDict(
        {1000: "M", 900: "CM", 500: "D", 400: "CD", 100: "C",
         90: "XC", 50: "L", 40: "XL", 10: "X", 9: "IX", 5: "V",
         4: "IV", 1: "I"})
    for i in roman_symbols:
        whole, reminder = divmod(whole, i)
        roman_number += whole * roman_symbols[i]
        whole = reminder

    return roman_number

if __name__ == '__main__':
    # These "asserts" using only for self-checking and not necessary for auto-testing
    assert checkio(6) == 'VI', '6'
    assert checkio(76) == 'LXXVI', '76'
    assert checkio(499) == 'CDXCIX', '499'
    assert checkio(3888) == 'MMMDCCCLXXXVIII', '3888'
    print('Done! Go Check!')


#jogo da mega sena
from time import sleep
from random import randint
lista = []
jogos = []

print('-'*30)
print('      JOGO DA MEGA SENA     ')
print('-'*30)
tot = 1
n = int(input('Quantos jogos você quer sortear: '))

while tot <=n:
    cont = 0

    if n == 0:
        break
    while True:
        r = randint(1,60)
        if r not in lista:
            lista.append(r)
            cont += 1
        if cont >= 6:
            break
    lista.sort()
    jogos.append(lista[:])
    lista.clear()
    tot +=1

print('-=' * 3, f' SORTEANDO {n} JOGOS ', '-='*3)
print()
for i in range (0,n):
    print(f'Jogo {i+1}: {jogos[i]}')
    sleep(1)
print()
print('-='*4, f' < BOA SORTE! > ', '-=' * 4)