import time
import random
import sys
from abc import abstractmethod

class Base(object):
    def __init__(self, name, desc):
        self.__name = name
        self.__desc = desc

    def __str__(self):
        return self.__name

    def get_name(self):
        return self.__name

    @abstractmethod
    def getInfo(self):
        return self.__desc

class House(Base):
    rooms = {}
    items = {}
    doors = {}

    def __init__(self, txt):
        Base.__init__(self, name='blue house', desc='')

    def add_room(cls,room):
        cls.rooms[room.get_name()]=room
        return room

    def new_room(self,name,desc):
        return self.add_room(Room(name,desc))

    def add_door(cls,door):
        cls.doors[door.get_name()]=door
        return door

    def new_door(self,direction,state,first,second):
        direction = direction.split('-')
        return self.add_door(Door(direction,state,self.rooms[first],self.rooms[second]))

    def add_item(cls,item):
        cls.items[item.get_name()]=item
        return item

    def new_item(self,name,room,state,func=None):
        if state == 'STATIONARY':
            return self.add_item(STATIONARYitem(name,self.rooms[room],state,func))
        elif state == 'USE':
            return self.add_item(USEitem(name,self.rooms[room],state,func))
        elif state == 'MOVE':
            return self.add_item(MOVEitem(name,self.rooms[room],state,func))

    def set_door(self, door):
        room1,room2 = door.first, door.second
        dir2,dir1 = tuple(door.way)
        room1.exit_ways[dir1] = door
        room2.exit_ways[dir2] = door

    def set_item(self,item):
        if not isinstance(item, USEitem):
            item.get_loc().inventory.add(item)
        else:
            item.get_loc().unseen.add(item)

directions = ['N','S','W','E']
start=time.mktime((1990,1,1,0,0,0,0,0,0))
end=time.mktime((2000,12,31,23,59,59,0,0,0))

def random_date(start,end):
    t=random.randint(start,end)
    date_touple=time.localtime(t)
    date=time.strftime("%Y-%m-%d",date_touple)
    return date

date = random_date(start, end)

class Game(Base):

    def __init__(self,name='Adventure'):
        Base.__init__(self, name, desc='')
        self.player = None

    def new_player(self, location):
        self.player = Player()
        self.player.set_location(location)
        return self.player

    def tiny_game(self):
        win = ['rock-scissors', 'scissors-paper','paper-rock']
        t = 0
        for _ in range(5):
            print()
            print("         Game is on! Rock, paper or scissors?")
            computer = random.choice(['rock', 'paper', 'scissors'])
            player = input('            Your turn:')
            print ("            Your choice: %s; Computer's choice: %s" % (player, computer))
            if player == computer:
                print( '            Peace')
            else:
                result = player + '-' + computer
                if result in win:
                    t += 1
                    print("         You win!")
                else:
                    print("         You lose!")
            if t > 1:
                return True
                break
        return False

    def run(self):

        while True:
            try:
                print("")
                user_input = input(">")
            except EOFError:
                break
            if user_input == 'quit' or user_input == 'q':
                raise SystemExit

            try:
                u = user_input.split()
                command = u[0]
                command = self.player.commands[command]
                try:
                    if len(u) > 1:
                        noun = u[1]
                        command(noun)
                    else:
                        command()
                except TypeError:
                    print("What do you want to {}?".format(u[0]))
            except Exception:
                print("I don't understand.")

class Inventory(Base):

    def __init__(self):
        self.__inventory_list = []

    def __str__(self):
        return "{0}".format(self.__inventory_list)

    def print_list(self):
        return ', '.join([i.get_name() for i in self.__inventory_list])

    def add(self, item):
        self.__inventory_list.append(item)

    def remove(self,item):
        if self.check(item):
            self.__inventory_list.remove(item)
            return item
        return None

    def pop(self):
        return self.__inventory_list.pop()

    def isempty(self):
        if len(self.__inventory_list) == 0:
            return True
        else:
            return False

    def check(self,item):
        if item in self.__inventory_list:
            return True
        else:
            return False

    def holding(self):
        if self.isempty():
            print("It's empty.")
        else:
            print("You have : {} ".format(self.print_list()))

class Player(Base):

    commands_help = {
            'show': 'the room info.',\
            'commands': 'all available commands in the game.',\
            'help': 'show details of command format and info',\
            'holding': 'lists all the items you are currently holding.',\
            'quit': 'ends the game.',\
            'go DIR': 'go to direction DIR.', \
            'open DIR': 'opens the door in direction DIR in the current room.', \
            'unlock DIR': 'when the door is locked and you have the key, you can use it to unlock the door.',\
            'take ITEM': 'take the thing from your current location.', \
            'release ITEM': 'drop the thing from you holdings.',\
            'check ITEM':"check stationary item", \
            'read ITEM': 'read readable item'}

    def __init__(self):
        Base.__init__(self,'You',desc='')
        self.inventory = Inventory()
        self.location = None
        self.game = Game()
        self.commands = {'go': self.act_go, 'show': self.act_show,\
                         'take': self.act_take, 'holding': self.act_holding,\
                        'commands': self.act_commands, 'help': self.act_help,\
                        'unlock': self.act_unlock, 'open': self.act_open, \
                        'check': self.act_check, 'read': self.act_read,\
                        'release': self.act_release
                        }

    def set_location(self,loc):
        self.location = loc
        # self.moved = True
        # if the actor moved, describe the room
        print("******You are now at the %s*******" %self.location.get_name())
        if self.location.get_name() == 'gate':
            print("Oh! What a great sunny day!")
            raise SystemExit

    # go DIR: Let’s the player move to the room in direction DIR,
    # if there is an open door in that direction.
    def act_go(self, dire):
        if not dire in directions:
            print("I don't understand. You can try %s." % '/'.join(directions))
            return False
        loc = self.location.check_way(dire)
        if loc == None:
            print("You cannot go that way.")
            return False
        else:
            self.set_location(loc)
            return True

    #show the description of the room, including doors and seen items.
    def act_show(self):
        if self.location:
            self.location.getInfo()

    #check holdings
    def act_holding(self):
        return self.inventory.holding()

    # take ITEM
    def act_take(self, item):
        item = House.items[item]
        thing = self.location.inventory.remove(item)
        if thing and isinstance(thing, USEitem):
            self.inventory.add(item)
            print("Taken the %s." %thing.get_name())
            return True
        else:
            print("You cannot take the %s." %item.get_name())
            return False

    # release ITEM
    def act_release(self, item):
        item = House.items[item]
        thing = self.inventory.pop(item,None)
        loc = self.location
        if thing:
            self.location.inventory.add(thing)
            thing.change_loc(loc)
            print("Released the %s." %thing.get_name())
            return True
        else:
            print("You don't have %s."%thing.get_name())
            return False

    # look at stationary item
    def act_check(self, item):
        item = House.items[item]
        if not isinstance(item, USEitem):
            if item.unchecked:
                if not self.location.unseen.isempty():
                    thing = self.location.unseen.pop()
                    self.location.inventory.add(thing)
                    item.unchecked = False
                    print("{} on the {}." .format(thing.get_name(), item.get_name()))
                    return True
            else:
                print("Nothing found.")
                return False
        else:
            print("I don't understand.")
            return False

    # read readable item
    def act_read(self,item):
        item = House.items[item]
        if item not in self.inventory:
            print("You should take that first.")
            return False
        if  not isinstance(item, USEitem) or item.func != 'read':
            print("I don't understand.")
            return False
        if item.get_name() == "calendar":
            print("Today is {}. \nToday is marked as anniversary. \nSay 'I love you' to her.".format(date))
            return True
        if item.get_name() == "book":
            result = self.game.tiny_game()
            if result:
                print("Well done!")
                door = self.location.exit_ways['N']
                door.open()
                return True
            else:
                print("You've run out of try.")
                # raise SystemExit
                return False
        if item.get_name() == 'letter':
            print('''
            Dear,
                I've made your favorite chicken soup for you. Remember to call me if you like it :)
            Your love
            ''')
        if item.get_name() == 'diary':
            print('''
            Day 1:
                It was a snowy day. I said to her. She accepted. How happy was I!
            Day 2:
                Great party!
                ...
            Day 100:
                I almost forgot the day. I should mark it on the calendar.''')

    def act_commands(cls):
        for c in cls.commands_help:
            print(c + " | " + cls.commands_help[c])

    def act_help(self):
        print('''
        Try 'commands' to show all the commands I understand.
        Enjoy your journey!''')
        # if command in UI.commands_help:
        #     print(UI.commands_help[command])
        # else:
        #     print("I don't understand.")
        #     self.act_commands()

    def act_unlock(self, dire):
        door = self.location.exit_ways[dire]
        if door.state == 'keylocked':
            if self.inventory.check(House.items['key']):
                door.open()
                print("Opened the door!")
                return True
            else:
                print("You don't have the key.")
                return False
        elif door.state == 'codelocked':
            user_try = input("Please input the code:")
            code = ''.join(date.split('-'))
            if user_try == code[-4:]:
                door.open()
                print("Opened the door!")
                return True
            else:
                print("Failed. Code is wrong.")
                return False

    def act_open(self, dire):
        door = self.location.exit_ways[dire]
        if door.state == 'closed':
            door.open()
            print("Opened the door.")
            return True
        print("You cannot open it.")
        return False

class Room(Base):
    def __init__(self,name, desc=''):
        Base.__init__(self, name, desc)
        self.exit_ways = {'N':None,'S':None,'W':None,'E':None}
        self.inventory=Inventory()
        self.unseen = Inventory()

    def getInfo(self):
        if self.inventory.isempty():
            print(super().getInfo() + '\n' + \
            "You have found doors towards: {}".format(self.all_doors()))
        else:
            print(super().getInfo() + '\n' + \
                "Found doors towards: {}".format(self.all_doors())  + '\n' + \
                "There is {} here.".format(self.inventory.print_list()))

    def all_doors(self):
        d = []
        for i in self.exit_ways:
            if self.exit_ways[i]:
                d.append(i)
        return ', '.join(d)

    def check_way(self,dire):
        door = self.exit_ways[dire]
        if door:
            if door.isopen():
                return door.way_to(dire)
            else:
                print("The door is %s." %door.state)
                return None
        return None

    def go(self,dire):
        loc = self.exit_ways[dire]
        if loc == None:
            print("You cannot go that way.")
            return False
        else:
            Player.set_location(loc)
            return True

class Door(Base):
    def __init__(self, direction,state,first,second, desc=''):
        self.__name = first.get_name() + '-' + second.get_name()
        Base.__init__(self, self.__name, desc)
        self.way = direction
        self.__directions = {'N':None,'S':None,'W':None,'E':None}
        self.state = state
        self.first = first
        self.second = second
        self.__directions[direction[0]] = self.first
        self.__directions[direction[1]] = self.second

    def open(self):
        self.state = 'open'

    def isopen(self):
        if self.state == 'open':
            return True
        return False

    def islocked(self):
        if self.state == 'locked':
            return True
        return False

    def way_to(self,dire):
        return self.__directions[dire]

class Item(Base):
    def __init__(self,name,room,state,func=None,desc=''):
        Base.__init__(self, name, desc)
        self.__location = room
        self.__state=state

    def get_loc(self):
        return self.__location

    def getInfo(self):
        print(super().getInfo())

class USEitem(Item):

    def __init__(self,name,room,state,func,desc=''):
        super().__init__(name,room,state,func,desc='')
        self.func = func

    def change_loc(self, loc):
        self.__location = loc

    def getInfo(self):
        print(super().getInfo())

class STATIONARYitem(Item):

    def __init__(self,name,room,state,desc=''):
        super().__init__(name,room,state,func=None,desc='')
        self.unchecked = True

    def getInfo(self):
        print(super().getInfo())

class MOVEitem(Item):

    def __init__(self,name,room,state,desc=''):
        super().__init__(name,room,state,func=None,desc='')
        self.unchecked = True

'''----------------------------------------------------------------------'''
if __name__ == "__main__":
    print('''Welcome to my house!
    if you need any 'help' please tell me!''')

    txt = sys.argv[1]
    house = House(txt)
    game = Game()
    player = game.new_player(house.start)
    game.player = player

    game.run()


"""
See https://en.wikipedia.org/wiki/Change-making_problem
"""

import satx

k = 13
coins = [1, 5, 10, 20, 50, 100, 200]

opt = k
while True:
    satx.engine(sum(coins).bit_length(), cnf_path='aux.cnf')

    x = satx.vector(size=len(coins))

    assert satx.dot(x, coins) == k

    assert sum(x) < opt

    if satx.satisfy('slime'):
        opt = sum(x)
        print(opt, x)
    else:
        break


from uptimer.events import DummyEvent
from uptimer.plugins.readers.dummies.dummy_events import Plugin

def test_dummy_events():
    p = Plugin()

    events = list(p.read())
    assert len(events) == 10
    for event in events:
        assert isinstance(event, DummyEvent)

def test_dummy_events_custom_count():
    p = Plugin(dummy_event_count=7)

    events = list(p.read())
    assert len(events) == 7


"""
Script to handle Zane related Math calculations

Arguments for mod: [Death Follows Close, Kill Skill Stacks, Active Action Skills, Movement Speed Over Base]

@author Prismatic
"""

def skillsSpec(skills, mods, gear):
    from utils import calcMain
    # Doubled Agent
    synchronicity = skills[0]
    donnybrook = skills[1]
    trick_of_the_light = skills[2]
    double_barrel = skills[3]

    # Hitman
    cold_bore = skills[4]
    violent_momentum = skills[5]
    death_follows_close = skills[6]

    # Under Cover
    confident_competence = skills[7]

    mods[0] = mods[0] + int(death_follows_close)
    normal_hit = [confident_competence, violent_momentum, synchronicity, donnybrook, double_barrel]

    normal = zane_normal_hit(normal_hit, mods) + gear[0]
    v1=0 + gear[1]
    v2=0 + gear[2]
    splash= 0 + gear[3]
    elemental = 0 + gear[4]
    critical = 0 + gear[5]
    bonus_cryo = (0.06 * int(cold_bore)) + (0.12 * int(trick_of_the_light)) + gear[6]

    mults = [normal, v1, v2, splash, elemental, critical, bonus_cryo]

    response, body, crit = calcMain.calc_Damage(mults)

    bonus_ele, body_1, crit_1 = calcMain.calc_bonus_elements(mults)
    if crit_1 != 0: response = response + "\n" + bonus_ele

    body = body + body_1
    crit = crit + crit_1

    response = response + "\n\nCombining Everything:\n**Peak Damage Multiplier:** " + str(round(body, 2)) + "\n**Peak Crit Damage Multiplier:** " + str(round(crit, 2))

    return response

"""
gun skills {confident_competence, violent_momentum, synchronicity, donnybrook, double_barrel}
skill modifiers {death_follows_close, kill_skill_stacks, active_action_skills, movement_speed_over_base}
"""
def zane_normal_hit(gun_skills, skill_modifiers):
    dfc = 1+0.25*float(skill_modifiers[0])
    return (0.35*float(gun_skills[0]))+(0.16*float(gun_skills[1])*skill_modifiers[3]*dfc)+(0.04*float(gun_skills[1])*dfc)+(0.04*float(gun_skills[2])*skill_modifiers[2])+(0.03*float(gun_skills[3])*dfc*skill_modifiers[1])+(0.25*float(gun_skills[4]))


import warnings

import numpy as np
import scipy as sp

import cvxpy.settings as s
from cvxpy.constraints import SOC, NonNeg, Zero
from cvxpy.reductions.solution import Solution, failure_solution
from cvxpy.reductions.solvers.conic_solvers.conic_solver import ConicSolver

class NAG(ConicSolver):
    """ An interface to the NAG SOCP solver
    """

    MIP_CAPABLE = False
    SUPPORTED_CONSTRAINTS = ConicSolver.SUPPORTED_CONSTRAINTS + [SOC]

    # Map of NAG status to CVXPY status
    STATUS_MAP = {0: s.OPTIMAL,
                  20: s.SOLVER_ERROR,
                  22: s.SOLVER_ERROR,
                  23: s.SOLVER_ERROR,
                  24: s.SOLVER_ERROR,
                  50: s.OPTIMAL_INACCURATE,
                  51: s.INFEASIBLE,
                  52: s.UNBOUNDED}

    def import_solver(self) -> None:
        """Imports the solver.
        """
        from naginterfaces.library import opt  # noqa F401

    def name(self):
        """The name of the solver.
        """
        return s.NAG

    def accepts(self, problem) -> bool:
        """Can NAG solve the problem?
        """
        if not problem.objective.args[0].is_affine():
            return False
        for constr in problem.constraints:
            if type(constr) not in self.SUPPORTED_CONSTRAINTS:
                return False
            for arg in constr.args:
                if not arg.is_affine():
                    return False
        return True

    def apply(self, problem):
        """Returns a new problem and data for inverting the new solution.

        Returns
        -------
        tuple
            (dict of arguments needed for the solver, inverse data)
        """
        data = dict()
        inv_data = dict()
        inv_data[self.VAR_ID] = problem.x.id

        if not problem.formatted:
            problem = self.format_constraints(problem, None)
        data[s.PARAM_PROB] = problem
        data[self.DIMS] = problem.cone_dims
        inv_data[self.DIMS] = problem.cone_dims
        constr_map = problem.constr_map

        c, d, A, b = problem.apply_parameters()
        A = -A
        data[s.C] = c.ravel()
        data[s.OBJ_OFFSET] = float(d)
        inv_data[s.OBJ_OFFSET] = float(d)
        inv_data['lin_dim'] = []
        inv_data['soc_dim'] = []
        Gs = list()
        hs = list()
        # Linear inequalities
        num_linear_eq = len(constr_map[Zero])
        num_linear_leq = len(constr_map[NonNeg])
        leq_dim = data[s.DIMS][s.LEQ_DIM]
        eq_dim = data[s.DIMS][s.EQ_DIM]
        if num_linear_leq > 0:
            offset = num_linear_eq
            for con in problem.constraints[offset:offset + num_linear_leq]:
                inv_data['lin_dim'].append((con.id, con.size))
            row_offset = eq_dim
            Gs.append(A[row_offset:row_offset + leq_dim])
            hs.append(b[row_offset:row_offset + leq_dim])
        # Linear equations
        if num_linear_eq > 0:
            for con in problem.constraints[:num_linear_eq]:
                inv_data['lin_dim'].append((con.id, con.size))
            Gs.append(A[:eq_dim])
            hs.append(b[:eq_dim])

        # Second order cones
        num_soc = len(constr_map[SOC])
        soc_dim = sum(data[s.DIMS][s.SOC_DIM])
        if num_soc > 0:
            offset = num_linear_eq + num_linear_leq
            for con in problem.constraints[offset:offset + num_soc]:
                inv_data['soc_dim'].append((con.id, con.size))
            row_offset = leq_dim + eq_dim
            Gs.append(A[row_offset:row_offset + soc_dim])
            hs.append(b[row_offset:row_offset + soc_dim])
        data['nvar'] = len(c) + sum(data[s.DIMS][s.SOC_DIM])
        inv_data['nr'] = len(c)
        if Gs:
            data[s.G] = sp.sparse.vstack(tuple(Gs))
        else:
            data[s.G] = sp.sparse.csc_matrix((0, 0))
        if hs:
            data[s.H] = np.hstack(tuple(hs))
        else:
            data[s.H] = np.array([])
        return (data, inv_data)

    def invert(self, solution, inverse_data):

        status = self.STATUS_MAP[solution['status']]
        sln = solution['sln']

        attr = {}
        if status in s.SOLUTION_PRESENT:
            opt_val = sln.rinfo[0] + inverse_data[s.OBJ_OFFSET]
            nr = inverse_data['nr']
            x = sln.x[0:nr]
            primal_vars = {inverse_data[self.VAR_ID]: x}
            attr[s.SOLVE_TIME] = sln.stats[5]
            attr[s.NUM_ITERS] = sln.stats[0]
            # Recover dual variables
            dual_vars = dict()
            lin_dim = sum(ell for _, ell in inverse_data['lin_dim'])
            if lin_dim > 0:
                lin_dvars = np.zeros(lin_dim)
                idx = 0
                for i in range(lin_dim):
                    lin_dvars[i] = sln.u[idx+1] - sln.u[idx]
                    idx += 2
                idx = 0
                for id, dim in inverse_data['lin_dim']:
                    if dim == 1:
                        dual_vars[id] = lin_dvars[idx]
                    else:
                        dual_vars[id] = np.array(lin_dvars[idx:(idx + dim)])
                    idx += dim
            soc_dim = sum(ell for _, ell in inverse_data['soc_dim'])
            if soc_dim > 0:
                idx = 0
                for id, dim in inverse_data['soc_dim']:
                    if dim == 1:
                        dual_vars[id] = sln.uc[idx]
                    else:
                        dual_vars[id] = np.array(sln.uc[idx:(idx + dim)])
                    idx += dim
            sol = Solution(status, opt_val, primal_vars, dual_vars, attr)
        else:
            sol = failure_solution(status)
        return sol

    def solve_via_data(self, data, warm_start: bool, verbose: bool, solver_opts, solver_cache=None):
        from naginterfaces.base import utils
        from naginterfaces.library import opt

        bigbnd = 1.0e20
        c = data[s.C]
        G = data[s.G]
        h = data[s.H]
        dims = data[s.DIMS]
        nvar = data['nvar']
        soc_dim = nvar - len(c)
        nleq = dims[s.LEQ_DIM]
        neq = dims[s.EQ_DIM]
        m = len(h)
        # declare the NAG problem handle
        handle = opt.handle_init(nvar)

        # define the linear objective
        cvec = np.concatenate((c, np.zeros(soc_dim)))
        opt.handle_set_linobj(handle, cvec)
        # define linear constraints
        rows, cols, vals = sp.sparse.find(G)
        lb = np.zeros(m)
        ub = np.zeros(m)
        lb[0:nleq] = -bigbnd
        lb[nleq:m] = h[nleq:m]
        ub = h
        if nvar > len(c):
            isoc_idx = nleq + neq
            jsoc_idx = len(c)
            rows = np.concatenate((rows, np.arange(isoc_idx, isoc_idx + soc_dim)))
            cols = np.concatenate((cols, np.arange(jsoc_idx, jsoc_idx + soc_dim)))
            vals = np.concatenate((vals, np.ones(soc_dim)))
        rows = rows + 1
        cols = cols + 1
        opt.handle_set_linconstr(handle, lb, ub, rows, cols, vals)

        # define the cones
        idx = len(c)
        size_cdvars = 0
        if soc_dim > 0:
            for size_cone in dims[s.SOC_DIM]:
                opt.handle_set_group(handle, gtype='Q',
                                     group=np.arange(idx+1, idx+size_cone+1),
                                     idgroup=0)
                idx += size_cone
                size_cdvars += size_cone

        # deactivate printing by default
        opt.handle_opt_set(handle, "Print File = -1")
        if verbose:
            opt.handle_opt_set(handle, "Monitoring File = 6")
            opt.handle_opt_set(handle, "Monitoring Level = 2")

        # Set the optional parameters
        kwargs = sorted(solver_opts.keys())
        if "nag_params" in kwargs:
            for option, value in solver_opts["nag_params"].items():
                optstr = option + '=' + str(value)
                opt.handle_opt_set(handle, optstr)
            kwargs.remove("nag_params")
        if kwargs:
            raise ValueError("invalid keyword-argument '{0}'".format(kwargs[0]))

        # Use an explicit I/O manager for abbreviated iteration output:
        iom = utils.FileObjManager(locus_in_output=False)

        # Promote warnings to exceptions
        warnings.simplefilter('error', utils.NagAlgorithmicWarning)
        warnings.simplefilter('error', utils.NagAlgorithmicMajorWarning)

        # Call SOCP interior point solver
        x = np.zeros(nvar)
        status = 0
        u = np.zeros(2*m)
        uc = np.zeros(size_cdvars)
        try:
            if soc_dim > 0:
                sln = opt.handle_solve_socp_ipm(handle, x=x, u=u, uc=uc, io_manager=iom)
            elif soc_dim == 0:
                sln = opt.handle_solve_lp_ipm(handle, x=x, u=u, io_manager=iom)
        except (utils.NagValueError, utils.NagAlgorithmicWarning,
                utils.NagAlgorithmicMajorWarning) as exc:
            status = exc.errno
            sln = exc.return_data
        # Destroy the handle:
        opt.handle_free(handle)

        return {'status': status, 'sln': sln}


"""
    Fondamentum by M. Virdis
"""
import quantopian.algorithm as algo
from quantopian.optimize import TargetWeights, NetExposure, PositionConcentration, MaximizeAlpha
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.data import Fundamentals
from quantopian.pipeline.data.morningstar import Fundamentals as MSFundamentals
from quantopian.pipeline.filters import QTradableStocksUS, Q500US, Q1500US
from scipy import stats
import numpy as np

def momentum_score(ts):
    """
    Input: security time series
    Output: annualized exp. regression slope * R2
    """
    # Create simple array [0, 1, 2, 3, ...] to use as x axis
    x = np.arange(len(ts))
    y = np.log(ts)

    slope,interc,r_val,p_val,std_err = stats.linregress(x,y)

    annual = (np.power(np.exp(slope),252)-1)*100

    return annual*(r_val**2)

def initialize(context):
    """
    Called once at the start of the algorithm.
    """
    # Rebalance
    algo.schedule_function(
        rebalance,
        algo.date_rules.month_end(), # SHOULD BE MONTH
        algo.time_rules.market_close(minutes=30)
    )

    # Record tracking variables at the end of each day.
    algo.schedule_function(
        record_vars,
        algo.date_rules.every_day(),
        algo.time_rules.market_close(minutes=15)
    )

    # Create our dynamic stock selector.
    algo.attach_pipeline(make_pipeline(), 'pipeline')

    # Set commissions
    algo.set_commission(commission.PerTrade(cost=19.0))
    #algo.set_commission(commission.NoCommission())
    #algo.set_commission(commission.PerShare(cost=.05))

    context.use_weights = True # If weights should be used in optimization

    context.filters = True         # use filtering?
    context.TF_lookback = 63       # How many days of SPY to look at
    context.can_buy_stocks = False # Triggered by bullish market
    context.can_buy = True

    context.bonds = [symbol('IEF'), symbol('SHY'), symbol('TLT')]

    context.num_stocks_to_trade = 20
    context.roe_top_n = 50      # How many top roe companies to keep
    context.momentum_days = 126 # How many days to check momentum
    context.score_to_go = 30    # Minimum Momentum score to consider a share
    context.days_to_skip = 10   # days before today to ignore in momentum

def make_pipeline():
    """
    A function to create our dynamic stock selector (pipeline). Documentation
    on pipeline can be found here:
    https://www.quantopian.com/help#pipeline-title
    """

    pipe = Pipeline(
        columns={'roe': Fundamentals.roe.latest,
                 'roic': Fundamentals.roic.latest,
                 'pb': MSFundamentals.pb_ratio.latest,
                 'cap': Fundamentals.market_cap.latest,
                 'close': USEquityPricing.close.latest},
        screen=Q1500US()
    )
    return pipe

def before_trading_start(context, data):
    """
    Called every day before market open.
    """
    # Safety checks--------

    if context.filters:
        # Check market conditions
        spy_hist = data.history(symbol('SPY'),'close',
                                context.TF_lookback+5,'1d')
        spy_momentum = spy_hist.pct_change(context.TF_lookback).iloc[-1]

        if spy_momentum > 0.0:
            context.can_buy_stocks = True
        else:
            context.can_buy_stocks = False
    else:
        context.can_buy = context.can_buy_stocks = True

def rebalance(context, data):
    """
    Execute orders according to our schedule_function() timing.
    """

    df = algo.pipeline_output('pipeline')

    # These are the securities that we are interested in trading each month.
    top_roe = df['roe'].nlargest(context.roe_top_n).index

    # Perform Momentum calculations for each security
    ranking = []
    for sec in top_roe:
        ts = data.history(sec,'price',context.momentum_days+context.days_to_skip+10,'1d')
        score = momentum_score(ts[:-context.days_to_skip])
        if score > context.score_to_go:
            ranking.append((score,sec))

    # Sort to rank each security based on momentum
    ranking.sort(reverse=True)

    sec_to_trade = [el[1] for el in ranking]
    sec_to_trade = sec_to_trade[:context.num_stocks_to_trade]

    # weights for next order
    weights = {}

    # First find positions to close
    for sec in context.portfolio.positions:
        if sec not in sec_to_trade:
            if sec not in context.bonds:
                weights[sec] = 0.0
            elif context.can_buy_stocks: # TODO Gradual decrease of bonds not all at once sold
                weights[sec] = 0.0

    # Compute remaining weights
    if context.can_buy_stocks and context.can_buy:

        for sec in sec_to_trade:
            weights[sec]=1.0/len(sec_to_trade)

    elif not context.can_buy_stocks and context.can_buy: # buy bonds

        cs = current_money_in_stocks(context)
        bond_weight = 1.0-(cs/context.portfolio.portfolio_value)

        for bond in context.bonds:
            if bond_weight > 0.0:
                weights[bond] = bond_weight/len(context.bonds)
            else:
                weights[bond] = 0.0

    if context.use_weights: # Use optimizer with weights
        objective = TargetWeights(weights)
        constraints = [
            NetExposure(0, 1.0)
        ]

        algo.order_optimal_portfolio(objective, constraints)

def current_money_in_stocks(context):
    ss = 0.0
    for sec in context.portfolio.positions:
        if sec in context.bonds:
            continue
        pos = context.portfolio.positions[sec]
        ss += pos.amount * pos.cost_basis

    return ss

def record_vars(context, data):
    """
    Plot variables at the end of each day.
    """
    ss = 0.0
    bs = 0.0
    for sec in context.portfolio.positions:
        pos = context.portfolio.positions[sec]
        if sec not in context.bonds:
            ss += pos.amount * pos.cost_basis
        else:
            bs += pos.amount * pos.cost_basis

    cash = context.portfolio.cash

    record(total_value=ss+cash+bs)
    record(stocks=ss)
    record(bonds=bs)
    record(cash=cash)


# [Programmers] 148653. 마법의 엘리베이터
# 풀이 시간: 70 분
# 실행 시간: 00 ms
# 메모리: 00 KB

# 고려할 경우: 1) 위로 올라가거나 2) 밑으로 내려가거나
def solution(storey):
    answer = []

    # st: 층, count: 마법의 돌 개수
    def dfs(st, count):
        # 종료 조건: 0층 도달
        if st == 0:
            answer.append(count)
            return

        one = st % 10
        up, down = 10 - one, one

        # up 이나 down 둘 중 더 적게 움직이는 쪽으로 이동
        if up < down:
            dfs(st // 10 + 1, count + up)
        elif down < up:
            dfs(st // 10, count + down)
        else:
            # 같다면 두 방향 모두 이동
            for i in range(2):
                dfs(st // 10 + i, count + up)

    dfs(storey, 0)
    # 최소값 반환
    return min(answer)


from os.path import join
from os import makedirs, environ
from pathlib import Path
import logging
from dotenv import dotenv_values, load_dotenv
from io import StringIO

logging.basicConfig(level=logging.DEBUG)
LOG = logging.getLogger(__name__)
LOCAL_DIR = join(Path.home(), ".pygadgets")

def try_make_dirs(directory):
    try:
        makedirs(directory)
    except OSError:
        LOG.info(f"{directory} already exists. skipping.")
    except Exception as e:
        raise RuntimeError(f"unhandled exceptions {str(e)}")
    else:
        LOG.info(".pygadget dir created")

try_make_dirs(join(LOCAL_DIR, "data"))
try_make_dirs(join(LOCAL_DIR, "log"))

try:
    env = dotenv_values(stream=StringIO(open(join(LOCAL_DIR, ".env"), "r").read()))
    LOG.info("loaded vars from .env")
except OSError:
    env = {k: v for k, v in environ.items() if k.startswith("PYGADGETS")}
    LOG.info("loaded vars from environ")

if env == {}:
    raise RuntimeError("Unable to collect configuration vars")

config = type("Config", (), env)


import numpy as np
import subprocess as sp
import os
import time
DEVNULL = open(os.devnull, 'w')

# attempts to handle all float/integer conversions with and without normalizing
def convert_bit_depth(y, in_type, out_type, normalize=False):
    in_type = np.dtype(in_type).type
    out_type = np.dtype(out_type).type

    if normalize:
        peak = np.abs(y).max()
        if peak == 0:
            normalize = False

    if issubclass(in_type, np.floating):
        if normalize:
            y /= peak
        if issubclass(out_type, np.integer):
            y *= np.iinfo(out_type).max
        y = y.astype(out_type)
    elif issubclass(in_type, np.integer):
        if issubclass(out_type, np.floating):
            y = y.astype(out_type)
            if normalize:
                y /= peak
        elif issubclass(out_type, np.integer):
            in_max = peak if normalize else np.iinfo(in_type).max
            out_max = np.iinfo(out_type).max
            if out_max > in_max:
                y = y.astype(out_type)
                y *= (out_max / in_max)
            elif out_max < in_max:
                y /= (in_max / out_max)
                y = y.astype(out_type)
    return y

# load_audio can not detect the input type
def ffmpeg_load_audio(filename, sr=44100, mono=False, normalize=True, in_type=np.int16, out_type=np.float32):
    in_type = np.dtype(in_type).type
    out_type = np.dtype(out_type).type
    channels = 1 if mono else 2
    format_strings = {
        np.float64: 'f64le',
        np.float32: 'f32le',
        np.int16: 's16le',
        np.int32: 's32le',
        np.uint32: 'u32le'
    }
    format_string = format_strings[in_type]
    command = [
        'ffmpeg',
        '-i', filename,
        '-f', format_string,
        '-acodec', 'pcm_' + format_string,
        '-ar', str(sr),
        '-ac', str(channels),
        '-']
    p = sp.Popen(command, stdout=sp.PIPE, stderr=DEVNULL)
    raw, err = p.communicate()
    audio = np.frombuffer(raw, dtype=in_type)

    if channels > 1:
        audio = audio.reshape((-1, channels)).transpose()

    if audio.size == 0:
        return audio.astype(out_type), sr

    audio = convert_bit_depth(audio, in_type, out_type, normalize)

    return audio, sr


"""
169. 多数元素
给定一个大小为 n 的数组，找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的，并且给定的数组总是存在多数元素。

示例 1：

输入：[3,2,3]
输出：3
示例 2：

输入：[2,2,1,1,1,2,2]
输出：2

进阶：

尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。
通过次数364,994提交次数549,614
"""
nums = [2, 2, 1, 1, 1, 1, 2, 2]

def majorityElement(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    length = len(nums)
    for i in set(nums):
        if nums.count(i) > length / 2:
            return i

print(majorityElement(nums))


from datetime import datetime
import numpy as np
import pandas as pd
import pandas_datareader as pdr
import os
from zipfile import ZipFile

def get_stocks(stock, start_dt, end_dt, id):
    DNE_list = []
    before_list = []

    if (end_dt-start_dt).days <= 0:
        return "Error", before_list

    stock_list = stock.split(',')
    with ZipFile('sampleDir%s.zip' % id, 'w') as zipObj:
        for stocks in stock_list:
            stocks = stocks.replace(" ", "")
            try:
                df = pdr.data.get_data_yahoo(stocks, start=start_dt, end=end_dt)

                """Check for date < start_dt"""
                time_str = str(df.index.values[0]).replace('T00:00:00.000000000', '')
                time = datetime.strptime(time_str, "%Y-%m-%d")
                if time.toordinal() > start_dt.toordinal()+7:
                    before_list.append(stocks)

                df.to_csv('%s.csv' % stocks)
                zipObj.write('%s.csv' % stocks)
            except:
                DNE_list.append(stocks)

    if dev:
        for stocks in stock_list:
            try:
                stocks = stocks.replace(" ", "")
                os.remove('%s.csv' % stocks)
            except:
                pass

    return DNE_list, before_list


LL = [int(x) for x in input().split()]
N = LL[0]
K = LL[1:]

def win(v):
    if v == 'ChuiZi':
        return 'Bu'
    elif v == 'Bu':
        return 'JianDao'
    else:
        return 'ChuiZi'
def lost(v):
    if v == 'ChuiZi':
        return 'JianDao'
    elif v == 'JianDao':
        return 'Bu'
    else:
        return 'ChuiZi'

vv = input()
idx = 0
while vv != 'End':
    idx += 1
    if idx > K[0]:
        print(lost(vv))
        K = K[1:] + [K[0]]
        idx = 0
    else:
        print(win(vv))
    vv = input()


import torch
import torch.nn as nn

# Task 5: Add FFN for Critic
class CriticNN(nn.Module):
    def __init__(self, input_size, output_size, hidden_size, n_layers):
        super(CriticNN, self).__init__()

        self.input_size = input_size
        self.output_size = output_size
        self.hidden_size = hidden_size
        self.n_layers = n_layers

        self.tanh = nn.Tanh()

        self.input_layer = nn.Linear(self.input_size, self.hidden_size)
        self.hidden_layer = nn.Linear(self.hidden_size, self.hidden_size)
        self.output_layer = nn.Linear(self.hidden_size, self.output_size)

    def forward(self, state):
        state = torch.as_tensor(state)

        network = self.tanh(self.input_layer(state))
        for i in range(self.n_layers):
            network = self.tanh(self.hidden_layer(network))
        network = self.output_layer(network)

        value = network.item()

        return value


import unittest

# Using cyclic sort - O(n) time ; O(1) space

def find_repeat(nums):
    # Find a number that appears more than once
    for i in range(len(nums)):
        while nums[i] != i + 1:
            j = nums[i] - 1
            if nums[i] == nums[j]:
                return nums[i]
            nums[i], nums[j] = nums[j], nums[i]
    return -1

# Using modified binary search:

# Tests

class Test(unittest.TestCase):

    def test_just_the_repeated_number(self):
        actual = find_repeat([1, 1])
        expected = 1
        self.assertEqual(actual, expected)

    def test_short_list(self):
        actual = find_repeat([1, 2, 3, 2])
        expected = 2
        self.assertEqual(actual, expected)

    def test_medium_list(self):
        actual = find_repeat([1, 2, 5, 5, 5, 5])
        expected = 5
        self.assertEqual(actual, expected)

    def test_long_list(self):
        actual = find_repeat([4, 1, 4, 8, 3, 2, 7, 6, 5])
        expected = 4
        self.assertEqual(actual, expected)

unittest.main(verbosity=2)


n=int(input())
for i in range(n):
    a,b=map(int,input().split())
    s=str(input())
    p=b
    for j in range(p):
        string=s[:b]
        string=string[::-1]
        s=string+s[b:]
        b -= 1
    print(s)


def gcd(n, m):
    """
    1. gcd(n, m) = gcd(n, n % m)
    2. gcd(n, n) = gcd(n, 0) = |n|
    3. gcd(n, 1) = 1
    4. for all 0 < y <= x, x % y <= x/2
    5. gcd(a, b) = gcd(b, a) = gcd(-a, b) = gcd(|a|, |b|)

    :param a:
    :param b:
    :return gcd(a, b):
    """
    n, m = abs(n), abs(m)
    if n < m:
        n, m = m, n
    while m > 0:
        temp = n
        n = m
        m = temp % m
    return n

class Solution:
    def fraction(self, cont: list) -> list:
        # 化简连分数
        a, b = cont[-1], 1  # a / b
        n = len(cont)

        index = n-2
        while index >= 0:
            a, b = cont[index] * a + b, a
            gcd_fac = gcd(a, b)
            a, b = a // gcd_fac, b // gcd_fac
            index -= 1

        return [a, b]

s = Solution()
assert [13, 4] == s.fraction(cont = [3, 2, 0, 2])
assert [3, 1] == s.fraction(cont = [0, 0, 3])


from flask_restful import reqparse, abort, Resource
from beacons_server import utils

class BasicResource(Resource):

    def __init__(self):
        self.table = self.__class__.__name__.lower()
        self.set_general_parser()
        self.set_get_parser()
        self.set_full_parser()

    def set_general_parser(self):
        self.parser = reqparse.RequestParser()
        self.parser.add_argument('position', type=int)
        self.parser.add_argument('name', trim=True)

    def set_get_parser(self):
        self.get_parser = self.parser.copy()
        self.get_parser.add_argument('_group_by', trim=True)
        self.get_parser.add_argument('_order_by', trim=True)
        self.get_parser.add_argument('_asc', trim=bool)
        self.get_parser.add_argument('_desc', trim=bool)
        self.get_parser.add_argument('_limit', trim=True)

    def set_full_parser(self):
        self.full_parser = self.parser.copy()
        self.full_parser.replace_argument('name', default='', trim=True)

    def abort_if_item_doesnt_exist(self, item):
        if item is None:
            abort(404, message="Could not find the specified item")

    def get(self, id = None):
        args = self.get_parser.parse_args()

        if id is None:
            return utils.get_db().select(self.table, orderBy='id', args=args)

        item = utils.get_db().select(self.table, unique=True, args=args, id=id)
        self.abort_if_item_doesnt_exist(item)

        return item

    def post(self):
        db = utils.get_db()

        args = self.full_parser.parse_args()
        id = db.insert_object(self.table, args)

        item = db.select(self.table, unique=True, id=id)
        return item, 201

    def delete(self, id):
        db = utils.get_db()

        item = db.select(self.table, unique=True, id=id)
        self.abort_if_item_doesnt_exist(item)

        db.remove_item(self.table, id)

        return '', 204

    def patch(self, id):
        db = utils.get_db()

        args = self.parser.parse_args()

        # Reposition item if needed
        db.move_item(self.table, id=id, new_position=args.get('position'), parent_id=args.get('parent_id'))

        # Update other item's attributes if any
        positionnal_keys = ['position', 'parent_id']
        args = {k:v for k,v in args.items() if k not in positionnal_keys and v != None}
        if len(args) > 0:
            db.update_item(self.table, id=id, args=args)

        updated_item = db.select(self.table, unique=True, id=id)
        if updated_item is None:
            self.abort_if_item_doesnt_exist(updated_item)
        return updated_item, 200


import multiprocessing as mp
import time
from os import getpid as pid

# A queue returns a process shared queue, is thread and process safe
class Producer(mp.Process):
    def __init__(self, q):
        mp.Process.__init__(self)
        self.q = q

    def run(self):
        for i in range(5):
            self.q.put(i)
            print("p-%s:%s" % (pid(), i))
            time.sleep(1)
        print('exit p-%s' % (pid(),))

class Consumer(mp.Process):
    def __init__(self, q):
        mp.Process.__init__(self)
        self.q = q

    def run(self):
        while not self.q.empty():
            print("c-%s:%s" % (pid(), self.q.get()))
            time.sleep(2)
        print('exit c-%s' % (pid(),))

queue = mp.Queue()
p_list = [Producer(queue), Producer(queue), Consumer(queue), Consumer(queue)]

for proc in p_list:
    proc.start()

for proc in p_list:
    proc.join()


#!/usr/bin/python3

# You must initialize the gobject/dbus support for threading
# before doing anything.
from __future__ import print_function
try:
    import gobject
except ImportError:
    from gi.repository import GObject as gobject
import sys
import time

gobject.threads_init()

from dbus import glib
glib.init_threads()

# Create a session bus.
import dbus

class RetrieveExportStats():
    def __init__(self):
        self.dbus_service_name = "org.ganesha.nfsd"
        self.dbus_exportstats_name = "org.ganesha.nfsd.exportstats"
        self.dbus_exportmgr_name = "org.ganesha.nfsd.exportmgr"
        self.export_interface = "/org/ganesha/nfsd/ExportMgr"

        self.bus = dbus.SystemBus()
        try:
            self.exportmgrobj = self.bus.get_object(self.dbus_service_name,
                                                    self.export_interface)
        except:
            print("Error: Can't talk to ganesha service on d-bus. Looks like Ganesha is down")
            sys.exit()

    # NFSv3/NFSv4/NLM/MNT/QUOTA stats over all exports
    def fast_stats(self):
        stats_op = self.exportmgrobj.get_dbus_method("GetFastOPS",
                                                     self.dbus_exportstats_name)
        return FastStats(stats_op())
    # NFSv3/NFSv40/NFSv41/NFSv42/NLM4/MNTv1/MNTv3/RQUOTA totalled over all exports
    def global_stats(self):
        stats_op = self.exportmgrobj.get_dbus_method("GetGlobalOPS",
                                                     self.dbus_exportstats_name)
        return GlobalStats(stats_op())
    # cache inode stats
    def inode_stats(self):
        stats_op = self.exportmgrobj.get_dbus_method("ShowCacheInode",
                                                     self.dbus_exportstats_name)
        return InodeStats(stats_op())
    # list of all exports
    def export_stats(self):
        stats_op = self.exportmgrobj.get_dbus_method("ShowExports",
                                                     self.dbus_exportmgr_name)
        return ExportStats(stats_op())

    # NFSv3/NFSv4/NLM/MNT/QUOTA stats totalled for a single export
    def total_stats(self, export_id):
        stats_op = self.exportmgrobj.get_dbus_method("GetTotalOPS",
                                                     self.dbus_exportstats_name)
        stats_dict = {}
        if export_id < 0:
            export_list = self.export_stats()
            for exportid in export_list.exportids():
                stats_dict[exportid] = stats_op(exportid)
        else:
            stats_dict[export_id] = stats_op(int(export_id))
        return TotalStats(stats_dict)

    def io_stats(self, stats_op, export_id):
        stats_dict = {}
        if export_id < 0:
            export_list = self.export_stats()
            for exportid in export_list.exportids():
                stats_dict[exportid] = stats_op(exportid)
            return stats_dict
        else:
            stats_dict[export_id] = stats_op(export_id)
            return stats_dict
    def v3io_stats(self, export_id):
        stats_op = self.exportmgrobj.get_dbus_method("GetNFSv3IO",
                                                     self.dbus_exportstats_name)
        return ExportIOv3Stats(self.io_stats(stats_op, export_id))
    def v4io_stats(self, export_id):
        stats_op = self.exportmgrobj.get_dbus_method("GetNFSv40IO",
                                                     self.dbus_exportstats_name)
        return ExportIOv4Stats(self.io_stats(stats_op, export_id))
    def pnfs_stats(self, export_id):
        stats_op = self.exportmgrobj.get_dbus_method("GetNFSv41Layouts",
                                                     self.dbus_exportstats_name)
        stats_dict = {}
        if export_id < 0:
            export_list = self.export_stats()
            for exportid in export_list.exportids():
                stats_dict[exportid] = stats_op(exportid)
            return PNFSStats(stats_dict)
        else:
            stats_dict[export_id] = stats_op(int(export_id))
            return PNFSStats(stats_dict)

    # Reset the statistics counters for all
    def reset_stats(self):
        stats_state = self.exportmgrobj.get_dbus_method("ResetStats",
                                                        self.dbus_exportstats_name)
        return StatsReset(stats_state())

    # fsal stats
    def fsal_stats(self, fsal):
        stats_op = self.exportmgrobj.get_dbus_method("GetFSALStats",
                                                     self.dbus_exportstats_name)
        return DumpFSALStats(stats_op(fsal))

    # enable stats
    def enable_stats(self, stat_type):
        stats_state = self.exportmgrobj.get_dbus_method("EnableStats",
                                                        self.dbus_exportstats_name)
        return StatsEnable(stats_state(stat_type))

    # disable stats
    def disable_stats(self, stat_type):
        stats_state = self.exportmgrobj.get_dbus_method("DisableStats",
                                                        self.dbus_exportstats_name)
        return StatsDisable(stats_state(stat_type))

    # status
    def status_stats(self):
        stats_state = self.exportmgrobj.get_dbus_method("StatusStats",
                                                        self.dbus_exportstats_name)
        return StatsStatus(stats_state())
    # v3_full
    def v3_full_stats(self):
        stats_state = self.exportmgrobj.get_dbus_method("GetFULLV3Stats",
                                                        self.dbus_exportstats_name)
        return DumpFULLV3Stats(stats_state())
    # v4_full
    def v4_full_stats(self):
        stats_state = self.exportmgrobj.get_dbus_method("GetFULLV4Stats",
                                                        self.dbus_exportstats_name)
        return DumpFULLV4Stats(stats_state())
    # authentication
    def auth_stats(self):
        stats_state = self.exportmgrobj.get_dbus_method("GetAuthStats",
                                                        self.dbus_exportstats_name)
        return DumpAuth(stats_state())
    # Export Details
    def export_details_stats(self, export_id):
        stats_op = self.exportmgrobj.get_dbus_method("GetExportDetails",
                                 self.dbus_exportstats_name)
        return ExportDetails(stats_op(export_id))

class RetrieveClientStats():
    def __init__(self):
        self.dbus_service_name = "org.ganesha.nfsd"
        self.dbus_clientstats_name = "org.ganesha.nfsd.clientstats"
        self.dbus_clientmgr_name = "org.ganesha.nfsd.clientmgr"
        self.client_interface = "/org/ganesha/nfsd/ClientMgr"

        self.bus = dbus.SystemBus()
        try:
            self.clientmgrobj = self.bus.get_object(self.dbus_service_name,
                                                    self.client_interface)
        except:
            print("Error: Can't talk to ganesha service on d-bus. Looks like Ganesha is down")
            sys.exit()

    # delegation stats related to a single client ip
    def deleg_stats(self, ip_):
        stats_op = self.clientmgrobj.get_dbus_method("GetDelegations",
                                                     self.dbus_clientstats_name)
        return DelegStats(stats_op(ip_))
    def list_clients(self):
        stats_op = self.clientmgrobj.get_dbus_method("ShowClients",
                                                     self.dbus_clientmgr_name)
        return Clients(stats_op())
    # Clients specific stats
    def client_io_ops_stats(self, ip):
        stats_op = self.clientmgrobj.get_dbus_method("GetClientIOops",
                          self.dbus_clientstats_name)
        return ClientIOops(stats_op(ip))
    def client_all_ops_stats(self, ip):
        stats_op = self.clientmgrobj.get_dbus_method("GetClientAllops",
                          self.dbus_clientstats_name)
        return ClientAllops(stats_op(ip))

class Clients():
    def __init__(self, clients):
        self._clients = clients
    def __str__(self):
        output = ("\nTimestamp: " + time.ctime(self._clients[0][0]) +
                  str(self._clients[0][1]) + " nsecs" +
                  "\nClient List:\n")
        for client in self._clients[1]:
            output += ("\nAddress: " + client[0] +
                       "\n\tNFSv3 stats available: " + str(client[1]) +
                       "\n\tMNT stats available: " + str(client[2]) +
                       "\n\tNLM4 stats available: " + str(client[3]) +
                       "\n\tRQUOTA stats available: " + str(client[4]) +
                       "\n\tNFSv4.0 stats available " + str(client[5]) +
                       "\n\tNFSv4.1 stats available: " + str(client[6]) +
                       "\n\tNFSv4.2 stats available: " + str(client[7]) +
                       "\n\t9P stats available: " + str(client[8]))
        return output

class DelegStats():
    def __init__(self, stats):
        self.curtime = time.time()
        self.status = stats[1]
        if stats[1] == "OK":
            self.timestamp = (stats[2][0], stats[2][1])
            self.curr_deleg = stats[3][0]
            self.curr_recall = stats[3][1]
            self.fail_recall = stats[3][2]
            self.num_revokes = stats[3][3]
    def __str__(self):
        if self.status != "OK":
            return "GANESHA RESPONSE STATUS: " + self.status
        self.starttime = self.timestamp[0] + self.timestamp[1] / 1e9
        self.duration = self.curtime - self.starttime
        return ("GANESHA RESPONSE STATUS: " + self.status +
                "\nStats collected since: " + time.ctime(self.timestamp[0]) + str(self.timestamp[1]) + " nsecs \n" +
                "\nDuration: " + "%.10f" % self.duration + " seconds" +
                "\nCurrent Delegations: " + str(self.curr_deleg) +
                "\nCurrent Recalls: " + str(self.curr_recall) +
                "\nCurrent Failed Recalls: " + str(self.fail_recall) +
                "\nCurrent Number of Revokes: " + str(self.num_revokes))

class ClientIOops():
    def __init__(self, stats):
        self.stats = stats
        self.status = stats[1]
        if stats[1] == "OK":
            self.timestamp = (stats[2][0], stats[2][1])
    def __str__(self):
        output = ""
        cnt = 3
        if self.status != "OK":
            return ("GANESHA RESPONSE STATUS: " + self.status)
        else:
            output += "\nClient last active at: " + time.ctime(self.timestamp[0]) + str(self.timestamp[1]) + " nsecs"
            j = 0
            while j<4:
                if self.stats[cnt]:
                    i = 0
                    if j==0:
                        output += "\n\t\tNFSv3:"
                    if j==1:
                        output += "\n\t\tNFSv4.0:"
                    if j==2:
                        output += "\n\t\tNFSv4.1:"
                    if j==3:
                        output += "\n\t\tNFSv4.2:"
                    output += "\n\t     total \t errors     transferred"
                    while  i<4:
                        if i==0:
                            output += "\nREAD :"
                        if i==1:
                            output += "\nWRITE:"
                        if i==2:
                            output += "\nOther:"
                        if i==3:
                            output += "\nLayout:"
                        output += "%12d" % self.stats[cnt+i+1][0]
                        output += " %12d" % self.stats[cnt+i+1][1]
                        if i<2:
                            output += " %12d" % self.stats[cnt+i+1][2]
                        if (i==2 and j<2):
                            i += 1
                        i += 1
                    if j<2:
                        cnt += 4
                    else:
                        cnt += 5
                else:
                    if j==0:
                        output += "\n\tNo NFSv3 activity"
                    if j==1:
                        output += "\n\tNo NFSv4.0 activity"
                    if j==2:
                        output += "\n\tNo NFSv4.1 activity"
                    if j==3:
                        output += "\n\tNo NFSv4.2 activity"
                    cnt += 1
                j += 1
            return output

class ClientAllops():
    def __init__(self, stats):
        self.stats = stats
        self.status = stats[1]
        if stats[1] == "OK":
            self.timestamp = (stats[2][0], stats[2][1])
    def __str__(self):
        output = ""
        cnt = 3
        if self.status != "OK":
            return ("GANESHA RESPONSE STATUS: " + self.status)
        else:
            output += "\nClient last active at: " + time.ctime(self.timestamp[0]) + str(self.timestamp[1]) + " nsecs"
            if self.stats[cnt]:
                output += "\n\t\tNFSv3 Operations"
                output += "\nOp Name    \t\t total \t errors     dups"
                tot_len = len(self.stats[cnt+1])
                i=0
                while (i+4) <= tot_len:
                    output += "\n" + (self.stats[cnt+1][i+0]).ljust(21)
                    output += " %s" % (str(self.stats[cnt+1][i+1]).rjust(9))
                    output += " %s" % (str(self.stats[cnt+1][i+2]).rjust(9))
                    output += " %s" % (str(self.stats[cnt+1][i+3]).rjust(9))
                    i += 4
                cnt += 2
            else:
                output += "\n\tNo NFSv3 activity"
                cnt += 1
            if self.stats[cnt]:
                output += "\n\t\tNLMv4 Operations"
                output += "\nOp Name    \t\t total \t errors     dups"
                tot_len = len(self.stats[cnt+1])
                i=0
                while (i+4) <= tot_len:
                    output += "\n" + (self.stats[cnt+1][i+0]).ljust(21)
                    output += " %s" % (str(self.stats[cnt+1][i+1]).rjust(9))
                    output += " %s" % (str(self.stats[cnt+1][i+2]).rjust(9))
                    output += " %s" % (str(self.stats[cnt+1][i+3]).rjust(9))
                    i += 4
                cnt += 2
            else:
                output += "\n\tNo NLMv4 activity"
                cnt += 1
            if self.stats[cnt]:
                output += "\n\t\tNFSv4 Operations"
                output += "\nOp Name    \t\t total \t errors"
                tot_len = len(self.stats[cnt+1])
                i=0
                while (i+3) <= tot_len:
                    output += "\n" + (self.stats[cnt+1][i+0]).ljust(21)
                    output += " %s" % (str(self.stats[cnt+1][i+1]).rjust(9))
                    output += " %s" % (str(self.stats[cnt+1][i+2]).rjust(9))
                    i += 3
                cnt += 2
            else:
                output += "\n\tNo NFSv4 activity"
                cnt += 1
            if self.stats[cnt]:
                output += "\n\t\tNFSv4 Compound Operations"
                output += "\n      total \t errors \t Ops in compond\n"
                output += " %s" % (str(self.stats[cnt+1][0]).rjust(9))
                output += " %s" % (str(self.stats[cnt+1][1]).rjust(9))
                output += " %s" % (str(self.stats[cnt+1][2]).rjust(9))
                cnt += 2
            else:
                output += "\n\tNo NFSv4 compound ops"
                cnt += 1
            return output

class Export():
    def __init__(self, export):
        self.exportid = export[0]
        self.path = export[1]
        self.nfsv3_stats_avail = export[2]
        self.nfsv40_stats_avail = export[6]
        self.nfsv41_stats_avail = export[7]
        self.nfsv42_stats_avail = export[8]
        self.mnt_stats_avail = export[3]
        self.nlmv4_stats_avail = export[4]
        self.rquota_stats_avail = export[5]
        self._9p_stats_avail = export[9]
    def __str__(self):
        return ("\nExport id: " + str(self.exportid) +
                "\n\tPath: " + self.path +
                "\n\tNFSv3 stats available: " + str(self.nfsv3_stats_avail) +
                "\n\tNFSv4.0 stats available: " + str(self.nfsv40_stats_avail) +
                "\n\tNFSv4.1 stats available: " + str(self.nfsv41_stats_avail) +
                "\n\tNFSv4.2 stats available: " + str(self.nfsv42_stats_avail) +
                "\n\tMNT stats available: " + str(self.mnt_stats_avail) +
                "\n\tNLMv4 stats available: " + str(self.nlmv4_stats_avail) +
                "\n\tRQUOTA stats available: " + str(self.rquota_stats_avail) +
                "\n\t9p stats available: " + str(self._9p_stats_avail) + "\n")

class ExportStats():
    def __init__(self, exports):
        self.curtime = time.time()
        self.timestamp = (exports[0][0], exports[0][1])
        self.exports = {}
        for export in exports[1]:
            exportid = export[0]
            self.exports[exportid] = Export(export)
    def __str__(self):
        self.starttime = self.timestamp[0] + self.timestamp[1] / 1e9
        self.duration = self.curtime - self.starttime
        output = ("Export Stats \n" +
                  "Stats collected since: " + time.ctime(self.timestamp[0]) + str(self.timestamp[1]) + " nsecs" +
                  "\nDuration: " + "%.10f" % self.duration + " seconds")
        for exportid in self.exports:
            output += str(self.exports[exportid])
        return output
    def exportids(self):
        return self.exports.keys()

class ExportDetails():
    def __init__(self, stats):
        self.stats = stats
        self.status = stats[1]
        if stats[1] == "OK":
            self.timestamp = (stats[2][0], stats[2][1])
    def __str__(self):
        output = ""
        cnt = 3
        if self.status != "OK":
            return ("GANESHA RESPONSE STATUS: " + self.status)
        else:
            output += "\nExport last accessed at: " + time.ctime(self.timestamp[0]) + str(self.timestamp[1]) + " nsecs"
            output += "\n   Latency is in milliseconds for Read/Write/Other Operations"
            j = 0
            while j<4:
                if self.stats[cnt]:
                    i = 0
                    if j==0:
                        output += "\n\t\tNFSv3:"
                    if j==1:
                        output += "\n\t\tNFSv4.0:"
                    if j==2:
                        output += "\n\t\tNFSv4.1:"
                    if j==3:
                        output += "\n\t\tNFSv4.2:"
                    output += "\n\t     total \t errors      latency/delays     transferred"
                    while  i<4:
                        if i==0:
                            output += "\nREAD :"
                        if i==1:
                            output += "\nWRITE:"
                        if i==2:
                            output += "\nOther:"
                        if i==3:
                            output += "\nLayout:"
                        output += "%12d" % self.stats[cnt+i+1][0]
                        output += " %12d" % self.stats[cnt+i+1][1]
                        if (j>1 and i==3):
                            output += " %12d" % self.stats[cnt+i+1][2]
                        else:
                            output += " %18.6f" % self.stats[cnt+i+1][2]
                        if i<2:
                            output += " %12d" % self.stats[cnt+i+1][3]
                        if (i==2 and j<2):
                            i += 1
                        i += 1
                    if j<2:
                        cnt += 4
                    else:
                        cnt += 5
                else:
                    if j==0:
                        output += "\n\tNo NFSv3 activity"
                    if j==1:
                        output += "\n\tNo NFSv4.0 activity"
                    if j==2:
                        output += "\n\tNo NFSv4.1 activity"
                    if j==3:
                        output += "\n\tNo NFSv4.2 activity"
                    cnt += 1
                j += 1
            return output

class GlobalStats():
    def __init__(self, stats):
        self.curtime = time.time()
        self.success = stats[0]
        self.status = stats[1]
        if self.success:
            self.timestamp = (stats[2][0], stats[2][1])
            self.nfsv3_total = stats[3][1]
            self.nfsv40_total = stats[3][3]
            self.nfsv41_total = stats[3][5]
            self.nfsv42_total = stats[3][7]
    def __str__(self):
        output = ""
        if not self.success:
            return "No NFS activity, GANESHA RESPONSE STATUS: " + self.status
        if self.status != "OK":
            output += self.status + "\n"
        self.starttime = self.timestamp[0] + self.timestamp[1] / 1e9
        self.duration = self.curtime - self.starttime
        output += ("Global Stats \n" +
                   "Stats collected since: " + time.ctime(self.timestamp[0]) + str(self.timestamp[1]) + " nsecs" +
                   "\nDuration: " + "%.10f" % self.duration + " seconds" +
                   "\nTotal NFSv3 ops: " + str(self.nfsv3_total) +
                   "\nTotal NFSv4.0 ops: " + str(self.nfsv40_total) +
                   "\nTotal NFSv4.1 ops: " + str(self.nfsv41_total) +
                   "\nTotal NFSv4.2 ops: " + str(self.nfsv42_total))
        return output

class InodeStats():
    def __init__(self, stats):
        self.stats = stats
    def __str__(self):
        output = ""
        if self.stats[1] != "OK":
            return "No NFS activity, GANESHA RESPONSE STATUS: " + self.stats[1]
        else:
            output += "\nTimestamp: " + time.ctime(self.stats[2][0]) + str(self.stats[2][1]) + " nsecs\n"
            output += "\nInode Cache statistics"
            output += "\n" + (self.stats[3][0]).ljust(25) + "%s" % (str(self.stats[3][1]).rjust(20))
            output += "\n" + (self.stats[3][2]).ljust(25) + "%s" % (str(self.stats[3][3]).rjust(20))
            output += "\n" + (self.stats[3][4]).ljust(25) + "%s" % (str(self.stats[3][5]).rjust(20))
            output += "\n" + (self.stats[3][6]).ljust(25) + "%s" % (str(self.stats[3][7]).rjust(20))
            output += "\n" + (self.stats[3][8]).ljust(25) + "%s" % (str(self.stats[3][9]).rjust(20))
            output += "\n" + (self.stats[3][10]).ljust(25) + "%s" % (str(self.stats[3][11]).rjust(20))
            output += "\n\nLRU Utilization Data"
            output += "\n" + (self.stats[4][0]).ljust(25) + "%s" % (str(self.stats[4][1]).rjust(20))
            output += "\n" + (self.stats[4][2]).ljust(25) + "%s" % (str(self.stats[4][3]).rjust(20))
            output += "\n" + (self.stats[4][4]).ljust(25) + (self.stats[4][5]).ljust(30)
            output += "\n" + (self.stats[4][6]).ljust(25) + "%s" % (str(self.stats[4][7]).rjust(20))
            output += "\n" + (self.stats[4][8]).ljust(25) + "%s" % (str(self.stats[4][9]).rjust(20))
        return output

class FastStats():
    def __init__(self, stats):
        self.curtime = time.time()
        self.stats = stats
    def __str__(self):
        if not self.stats[0]:
            return "No NFS activity, GANESHA RESPONSE STATUS: " + self.stats[1]
        else:
            if self.stats[1] != "OK":
                output = self.stats[1]+ "\n"
            else:
                output = ""
            self.starttime = self.stats[2][0] + self.stats[2][1] / 1e9
            self.duration = self.curtime - self.starttime
            output += ("Fast stats" +
                       "\nStats collected since: " + time.ctime(self.stats[2][0]) + str(self.stats[2][1]) + " nsecs" +
                       "\nDuration: " + "%.10f" % self.duration + " seconds" +
                       "\nGlobal ops:\n")
            # NFSv3, NFSv4, NLM, MNT, QUOTA self.stats
            for i in range(0, len(self.stats[3])-1):
                if ":" in str(self.stats[3][i]):
                    output += self.stats[3][i] + "\n"
                elif str(self.stats[3][i]).isdigit():
                    output += "\t%s" % (str(self.stats[3][i]).rjust(8)) + "\n"
                else:
                    output += "%s: " % (self.stats[3][i].ljust(20))
        return output

class ExportIOv3Stats():
    def __init__(self, stats):
        self.stats = stats
    def __str__(self):
        output = ""
        for key in self.stats:
            if not self.stats[key][0]:
                output += "EXPORT %s: %s\n" % (key, self.stats[key][1])
                continue
            if self.stats[key][1] != "OK":
                output += self.stats[key][1] + "\n"
            output += ("\nEXPORT %s:" % (key) +
                       "\n\t\trequested\ttransferred\t     total\t    errors\t   latency" +
                       "\nREADv3: ")
            for stat in self.stats[key][3]:
                output += "\t" + str(stat).rjust(8)
            output += "\nWRITEv3: "
            for stat in self.stats[key][4]:
                output += "\t" + str(stat).rjust(8)
        return output

class ExportIOv4Stats():
    def __init__(self, stats):
        self.stats = stats
    def __str__(self):
        output = ""
        for key in self.stats:
            if not self.stats[key][0]:
                output += "\nEXPORT %s: %s\n" % (key, self.stats[key][1])
                continue
            if self.stats[key][1] != "OK":
                output += self.stats[key][1] + "\n"
            output += ("EXPORT %s:" % (key) +
                       "\n\t\trequested\ttransferred\t     total\t    errors\t   latency" +
                       "\nREADv4: ")
            for stat in self.stats[key][3]:
                output += "\t" + str(stat).rjust(8)
            output += "\nWRITEv4: "
            for stat in self.stats[key][4]:
                output += "\t" + str(stat).rjust(8)
            output += "\n\n"
        return output

class TotalStats():
    def __init__(self, stats):
        self.curtime = time.time()
        self.stats = stats
    def __str__(self):
        output = ""
        key = next(iter(self.stats))
        self.starttime = self.stats[key][2][0] + self.stats[key][2][1] / 1e9
        self.duration = self.curtime - self.starttime
        output += ("Total stats for export(s) \n" +
                   "Stats collected since: " + time.ctime(self.stats[key][2][0]) +
                   str(self.stats[key][2][1]) + " nsecs" +
                   "\nDuration: " + "%.10f" % self.duration + " seconds ")
        for key in self.stats:
            if not self.stats[key][0]:
                return "No NFS activity, GANESHA RESPONSE STATUS: " + self.stats[key][1]
            if self.stats[key][1] != "OK":
                output += self.stats[key][1] + "\n"
            output += "\nExport id: " + str(key)
            for i in range(0, len(self.stats[key][3])-1, 2):
                output += "\n\t%s: %s" % (self.stats[key][3][i], self.stats[key][3][i+1])
        return output

class PNFSStats():
    def __init__(self, stats):
        self.curtime = time.time()
        self.stats = stats
    def __str__(self):
        output = "PNFS stats for export(s)"
        for key in self.stats:
            if self.stats[key][1] != "OK":
                return "No NFS activity, GANESHA RESPONSE STATUS: \n" + self.stats[key][1]
            self.starttime = self.stats[key][2][0] + self.stats[key][2][1] / 1e9
            self.duration = self.curtime - self.starttime
            output += ("\nStats collected since: " + time.ctime(self.stats[key][2][0]) + str(self.stats[key][2][1]) + " nsecs" +
                       "\nDuration: " + "%.10f" % self.duration + " seconds\n")
            output += "\nStatistics for:" + str(exports[1]) +" export id: "+ str(key)
            output += "\n\t\ttotal\terrors\tdelays" + "getdevinfo "
            for stat in self.stats[key][3]:
                output += "\t" + stat
            output += "layout_get "
            for stat in self.stats[key][4]:
                output += "\t" + stat
            output += "layout_commit "
            for stat in self.stats[key][5]:
                output += "\t" + stat
            output += "layout_return "
            for stat in self.stats[key][6]:
                output += "\t" + stat
            output += "recall "
            for stat in self.stats[key][7]:
                output += "\t" + stat
        return output

class StatsReset():
    def __init__(self, status):
        self.status = status
    def __str__(self):
        if self.status[1] != "OK":
            return "Failed to reset statistics, GANESHA RESPONSE STATUS: " + self.status[1]
        else:
            return "Successfully resetted statistics counters"

class StatsStatus():
    def __init__(self, status):
        self.status = status
    def __str__(self):
        output = ""
        if not self.status[0]:
            return "Unable to fetch current status of stats counting: " + self.status[1]
        else:
            if self.status[2][0]:
                output += "Stats counting for NFS server is enabled since: \n\t"
                output += time.ctime(self.status[2][1][0]) + str(self.status[2][1][1]) + " nsecs\n"
            else:
                output += "Stats counting for NFS server is currently disabled\n"
            if self.status[3][0]:
                output += "Stats counting for FSAL is enabled since: \n\t"
                output += time.ctime(self.status[3][1][0]) + str(self.status[3][1][1]) + " nsecs\n"
            else:
                output += "Stats counting for FSAL is currently disabled \n"
            if self.status[4][0]:
                output += "Stats counting for v3_full is enabled since: \n\t"
                output += time.ctime(self.status[4][1][0]) + str(self.status[4][1][1]) + " nsecs\n"
            else:
                output += "Stats counting for v3_full is currently disabled \n"
            if self.status[5][0]:
                output += "Stats counting for v4_full is enabled since: \n\t"
                output += time.ctime(self.status[5][1][0]) + str(self.status[5][1][1]) + " nsecs\n"
            else:
                output += "Stats counting for v4_full is currently disabled \n"
            if self.status[6][0]:
                output += "Stats counting for authentication is enabled since: \n\t"
                output += time.ctime(self.status[6][1][0]) + str(self.status[6][1][1]) + " nsecs\n"
            else:
                output += "Stats counting for authentication is currently disabled \n"
            if self.status[7][0]:
                output += "Stats counting of all ops for client is enabled since: \n\t"
                output += time.ctime(self.status[7][1][0]) + str(self.status[7][1][1]) + " nsecs\n"
            else:
                output += "Stats counting of all ops for client is currently disabled \n"
            return output

class DumpFSALStats():
    def __init__(self, stats):
        self.curtime = time.time()
        self.stats = stats
    def __str__(self):
        output = ""
        if not self.stats[0]:
            return "GANESHA RESPONSE STATUS: " + self.stats[1]
        else:
            if self.stats[3] == "GPFS":
                if self.stats[5] != "OK":
                    output += "No stats available for display"
                    return output
                self.starttime = self.stats[2][0] + self.stats[2][1] / 1e9
                self.duration = self.curtime - self.starttime
                output += "FSAL stats for - GPFS \n"
                output += "Stats collected since: " + time.ctime(self.stats[2][0]) + str(self.stats[2][1]) + " nsecs\n"
                output += "Duration: " + "%.10f" % self.duration + " seconds\n"
                tot_len = len(self.stats[4])
                output += "FSAL Stats (response time in milliseconds): \n"
                output += "\tOp-Name         Total     Res:Avg         Min           Max"
                i = 0
                while (i+5) <= tot_len:
                    output += "\n" + (self.stats[4][i+0]).ljust(20)
                    output += " %s" % (str(self.stats[4][i+1]).rjust(8))
                    output += " %12.6f" % (self.stats[4][i+2])
                    output += " %12.6f" % (self.stats[4][i+3])
                    output += " %12.6f" % (self.stats[4][i+4])
                    i += 5
                return output

class StatsEnable():
    def __init__(self, status):
        self.status = status
    def __str__(self):
        if self.status[1] != "OK":
            return "Failed to enable statistics counting, GANESHA RESPONSE STATUS: " + self.status[1]
        else:
            return "Successfully enabled statistics counting"

class StatsDisable():
    def __init__(self, status):
        self.status = status
    def __str__(self):
        if self.status[1] != "OK":
            return "Failed to disable statistics counting, GANESHA RESPONSE STATUS: " + self.status[1]
        else:
            return "Successfully disabled statistics counting"

class DumpAuth():
    def __init__(self, stats):
        self.curtime = time.time()
        self.success = stats[0]
        self.status = stats[1]
        if self.success:
            self.timestamp = (stats[2][0], stats[2][1])
            self.gctotal = stats[3][0]
            self.gclatency = stats[3][1]
            self.gcmax = stats[3][2]
            self.gcmin = stats[3][3]
            self.wbtotal = stats[3][4]
            self.wblatency = stats[3][5]
            self.wbmax = stats[3][6]
            self.wbmin = stats[3][7]
    def __str__(self):
        output = ""
        if not self.success:
            return "No auth activity, GANESHA RESPONSE STATUS: " + self.status
        if self.status != "OK":
            output += self.status + "\n"
        self.starttime = self.timestamp[0] + self.timestamp[1] / 1e9
        self.duration = self.curtime - self.starttime
        output += ("Authentication related stats" +
                   "\nStats collected since: " + time.ctime(self.timestamp[0]) + str(self.timestamp[1]) + " nsecs"+
                   "\nDuration: " + "%.10f" % self.duration + " seconds\n" +
                   "\n\nGroup Cache" +
                   "\n\tTotal ops: " + str(self.gctotal) +
                   "\n\tAve Latency: " + str(self.gclatency) +
                   "\n\tMax Latency: " + str(self.gcmax) +
                   "\n\tMin Latency: " + str(self.gcmin) +
                   "\n\nWinbind" +
                   "\n\tTotal ops: " + str(self.wbtotal) +
                   "\n\tAve Latency: " + str(self.wblatency) +
                   "\n\tMax Latency: " + str(self.wbmax) +
                   "\n\tMin Latency: " + str(self.wbmin))
        return output

class DumpFULLV3Stats():
    def __init__(self, status):
        self.curtime = time.time()
        self.stats = status
    def __str__(self):
        output = ""
        if not self.stats[0]:
            return "Unable to fetch Detailed NFSv3 stats - " + self.stats[1]
        else:
            if self.stats[4] != "OK":
                output += "\n No stats available for display"
                return output
            self.starttime = self.stats[2][0] + self.stats[2][1] / 1e9
            self.duration = self.curtime - self.starttime
            output += "NFSv3 Detailed statistics \n"
            output += "Stats collected since: " + time.ctime(self.stats[2][0]) + str(self.stats[2][1]) + " nsecs\n"
            output += "Duration: " + "%.10f" % self.duration + " seconds\n"
            output += "\nOperation Details                         |  Operation Latency (in milliseconds)"
            output += "\n==========================================|========================================"
            output += "\nName            Total     Error      Dups |       Avg          Min           Max   "
            i = 0
            tot_len = len(self.stats[3])
            while i < tot_len:
                output += "\n" + (self.stats[3][i][0]).ljust(11)
                output += " %s" % (str(self.stats[3][i][1]).rjust(9))
                output += " %s" % (str(self.stats[3][i][2]).rjust(9))
                output += " %s |" % (str(self.stats[3][i][3]).rjust(9))
                output += " %12.6f" % (self.stats[3][i][4])
                output += " %12.6f" % (self.stats[3][i][5])
                output += " %12.6f" % (self.stats[3][i][6])
                i += 1
            return output

class DumpFULLV4Stats():
    def __init__(self, status):
        self.curtime = time.time()
        self.stats = status
    def __str__(self):
        output = ""
        if not self.stats[0]:
            return "Unable to fetch Detailed NFSv4 stats - " + self.stats[1]
        else:
            if self.stats[4] != "OK":
                output += "\n No stats available for display"
                return output
            self.starttime = self.stats[2][0] + self.stats[2][1] / 1e9
            self.duration = self.curtime - self.starttime
            output += "NFSv4 Detailed statistics \n"
            output += "Stats collected since: " + time.ctime(self.stats[2][0]) + str(self.stats[2][1]) + " nsecs\n"
            output += "Duration: " + "%.10f" % self.duration + " seconds\n"
            output += "\nOperation Details                            |  Operation Latency (in milliseconds)"
            output += "\n=============================================|========================================"
            output += "\nName                        Total     Error  |       Avg          Min           Max   "
            i = 0
            tot_len = len(self.stats[3])
            while i < tot_len:
                output += "\n" + (self.stats[3][i][0]).ljust(23)
                output += " %s" % (str(self.stats[3][i][1]).rjust(9))
                output += " %s  |" % (str(self.stats[3][i][2]).rjust(9))
                output += " %12.6f" % (self.stats[3][i][3])
                output += " %12.6f" % (self.stats[3][i][4])
                output += " %12.6f" % (self.stats[3][i][5])
                i += 1
            return output


import logging
logger = logging.getLogger(__name__)

from django.contrib.auth.models import User
from django.test import TestCase
from django.test.client import Client

from lxml import etree

from tardis.tardis_portal.models import \
    Experiment, ExperimentACL, License, UserProfile

from tardis.tardis_portal.models import ExperimentParameter, \
    ExperimentParameterSet, ParameterName, Schema

from django.conf import settings

def _create_test_data():
    """
    Create Single experiment with two owners
    """
    user1 = User(username='tom',
                first_name='Thomas',
                last_name='Atkins',
                email='tommy@atkins.net')
    user1.save()
    UserProfile(user=user1).save()

    user2 = User(username='joe',
                first_name='Joe',
                last_name='Bloggs',
                email='joe@mail.com')
    user2.save()
    UserProfile(user=user2).save()

    license_ = License(name='Creative Commons Attribution-'
        + 'NoDerivs 2.5 Australia',
                       url='http://creativecommons.org/licenses/by-nd/2.5/au/',
                       internal_description='CC BY 2.5 AU',
                       allows_distribution=True)
    license_.save()
    experiment = Experiment(title='Norwegian Blue',
                            description='Parrot + 40kV',
                            created_by=user1)
    experiment.public_access = Experiment.PUBLIC_ACCESS_FULL
    experiment.license = license_
    experiment.save()
    experiment.author_experiment_set.create(order=0,
                                        author="John Cleese",
                                        url="http://nla.gov.au/nla.party-1")
    experiment.author_experiment_set.create(order=1,
                                        author="Michael Palin",
                                        url="http://nla.gov.au/nla.party-2")

    acl1 = ExperimentACL(experiment=experiment,
                    pluginId='django_user',
                    entityId=str(user1.id),
                    isOwner=True,
                    canRead=True,
                    canWrite=True,
                    canDelete=True,
                    aclOwnershipType=ExperimentACL.OWNER_OWNED)
    acl1.save()

    acl2 = ExperimentACL(experiment=experiment,
                    pluginId='django_user',
                    entityId=str(user2.id),
                    isOwner=True,
                    canRead=True,
                    canWrite=True,
                    canDelete=True,
                    aclOwnershipType=ExperimentACL.OWNER_OWNED)
    acl2.save()

    sch, _ = Schema.objects.get_or_create(namespace=settings.KEY_NAMESPACE,
                                          name=settings.KEY_NAME,
                                          type=Schema.EXPERIMENT)

    pn, _ = ParameterName.objects.\
            get_or_create(schema=sch, name=settings.KEY_NAME,
                data_type=ParameterName.STRING)

    return experiment

class DOITest(TestCase):

    def setUp(self):
        pass

    def test_mint(self):
        import json
        client = Client()
        experiment = _create_test_data()
        response = client.get('/apps/reposproducer/key/%s/'
            % experiment.id,
            follow=True)

        response_obj = json.loads(response.content)
        self.assertTrue(response_obj)

        response = client.get('/apps/reposproducer/key/%s/'
            % experiment.id,
            follow=True)
        new_response_obj = json.loads(response.content)
        self.assertEquals(new_response_obj, response_obj)


import cv2
import numpy as np

def read_img(img):
    (_, thresh) = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)
    kernel_2 = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))    # 形态学处理:定义矩形结构
    closed_2 = cv2.erode(thresh, kernel_2, iterations=2)            # 闭运算：迭代2次

    kernel_5 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))    # 形态学处理:定义矩形结构
    closed_5 = cv2.erode(thresh, kernel_5, iterations=5)            # 闭运算：迭代5次

    cv2.imshow('original_img', img)
    cv2.imshow("closed_2",closed_2)
    cv2.imshow("closed_5",closed_5)
    cv2.waitKey(0)
    return closed_2,closed_5

def project_img(image):
    height, width = image.shape[:2]
    print("image.shape",image.shape)

    # 垂直投影：统计并存储每一列的黑点数
    vertical = np.zeros(width,dtype=np.int32)
    for x in range(0, width):
        for y in range(0, height):
            if image[y, x] == 0:
                vertical[x]+=1

    # 水平投影  #统计每一行的黑点数
    horizontal = np.zeros(height,dtype=np.int32)
    for y in range(0, height):
        for x in range(0, width):
            if image[y, x] == 0:
                horizontal[y] += 1

    # 创建空白图片，绘制垂直投影图
    emptyImage = np.zeros((height, width, 3), np.uint8)
    for x in range(0, width):
        for y in range(0, vertical[x]):
            b = (255, 255, 255)
            emptyImage[y, x] = b

    # 绘制水平投影图
    emptyImage1 = np.zeros((height, width, 3), np.uint8)
    for y in range(0, height):
        for x in range(0, horizontal[y]):
            b = (255, 255, 255)
            emptyImage1[y, x] = b

    cv2.imshow('chuizhi', emptyImage)
    cv2.imshow('shuipin', emptyImage1)
    cv2.waitKey(0)

if __name__ == '__main__':
    img = cv2.imread('../img/wan.png')
    print("img",img.shape)
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    retval, threshold_img = cv2.threshold(gray_img, 200, 255, cv2.THRESH_TOZERO)
    retval, threshold_img = cv2.threshold(threshold_img, 200, 255, cv2.THRESH_BINARY)
    dilate_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (6, 8))

    # 获得胀化后的图像
    dilate_img = cv2.dilate(threshold_img, dilate_kernel)
    # closed_2, closed_5 = read_img(img)
    project_img(dilate_img)
    # project_img(closed_5)
    cv2.destroyAllWindows()


from typing import Any, List, Optional, Tuple

import torch
import torchvision
from torchvision import models
from torch import Tensor
from torchattacks import PGD

from ...lib.trace import Trace, trace as _trace

# hack to support Python 3.10
# for Python 3.11 and higher, import Self from typing
Self = Any

class ImageManipulator:
    """
    A class for applying transformations to images.

    While a manipulator operates on a copy of the input image, each
    manipulator makes a sequence of modifications in-place. Reuse of
    manipulators should be done with caution, as intermediate results will not
    be maintained.
    """

    def __init__(self, image: Tensor,
                 random_state: Optional[int] = None) -> None:
        """
        Initializes a new StructuredManipulator. Note that this creates a deep
        copy of the entire passed dataset.

        :param image: The image to manipulate.
        :param random_state: A random state for reproducibility in stochastic
            operations.
        :return: None
        """
        self.random_state = random_state

        self.image = torch.clone(image)

        self._traces: List[Trace] = []

    @property
    def trace(self) -> str:
        """
        Returns a traceback of all operations performed on the manipulator.

        :return: Newline-separated traceback of all operations performed.
        """
        return "\n".join(str(t) for t in self._traces)

    @_trace
    def noise_attack(self, std: float = 250.0) -> Self:
        """
        Apply random noise to an image.

        :param std: The standard deviation of the Gaussian noise.
        :return: self
        """
        mean = torch.zeros(self.image.shape)
        std = torch.ones(self.image.shape) * std
        noise = torch.normal(mean, std)

        self.image = torch.clip(self.image + noise, min=0, max=1.0).float()

        return self, {"std": std}

    @_trace
    def blur_attack(self, kernel_size: int = 15) -> Self:
        """
        Apply a Gaussian blur to an image.

        :param kernel_size: The size of the blur kernel to be applied.
        :return: self
        """
        transform = torchvision.transforms.GaussianBlur(kernel_size=kernel_size)
        self.image = transform(self.image)

        return self, {}

    @_trace
    def occlusion_attack(self) -> Self:
        """
        Occlude a region of the image.

        :return: self
        """
        transform = torchvision.transforms.RandomErasing(p=1)
        self.image = transform(self.image)

        return self, {}

    @_trace
    def dual_class_attack(self, image: Tensor, dataset: Tensor,
                          loc: Tuple[int, int] = None) -> Self:
        """
        Create a dual-class image by injecting another image.

        :param image: The image to be modified
        :param dataset: A dataset from which to draw image to be injected
        :param loc: Location of image to be injected. Defaults to random
        :return: self
        """
        to_pil = torchvision.transforms.ToPILImage()
        to_tensor = torchvision.transforms.ToTensor()
        i = torch.randint(len(dataset), size=(1, 1))[0]
        foreground = to_pil(dataset[i].squeeze()).convert("RGBA")
        background = to_pil(image.squeeze()).convert("RGBA")
        bg_size = background.size
        new_size = int(bg_size[0] / 3)

        if loc is None:
            loc1 = torch.randint(int(2 * bg_size[0] / 3), size=(1, 1))[0]
            loc2 = torch.randint(int(2 * bg_size[0] / 3), size=(1, 1))[0]
            loc = (loc1, loc2)

        foreground = foreground.resize((new_size, new_size))
        background.paste(foreground, loc, foreground)
        background = background.convert("RGB")

        self.image = to_tensor(background)
        return self, {"dataset": dataset,
                      "loc": loc}

    @_trace
    def adversarial_attack(self, model=None) -> Self:
        """
        Apply torch adversarial attack to an image.

        :param model: The torch model to use for the attack.
        :return: self
        """
        image = self.image.unsqueeze(dim=0)
        device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
        if model is None:
            model = (models.resnet50(weights=models.ResNet50_Weights.IMAGENET1K_V1)
                        .to(device).eval())
        transform = torchvision.transforms.Compose([
        torchvision.transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                        std=[0.229, 0.224, 0.225]),
        ])
        input = transform(image).to(device)
        logits = model(input)
        label = torch.nn.functional.softmax(logits, dim=1).argmax()
        label = label.unsqueeze(dim=0)
        atk = PGD(model, eps=8/255, alpha=2/225, steps=10, random_start=True)

        output = atk(image, label).cpu()

        self.image = output
        return self, {}


# hint: 가능한 조합에서 중복이 발생하지 않는 경우 최소성을 만족하는지 확인, 문자열 in 은 덩어리를 하나로 인식함->set으로 판별

import itertools
def solution(arr):
    key=[]
    n=len(arr[0])   # 속성 수
    m=len(arr)      # 튜플수
    tmp=[]
    for i in range(1,n+1):
        tmp+=[*map(list,itertools.combinations(range(n),i))]
    for i in tmp:
        cand = "".join(map(str, i))
        flag = 1
        for p in key:
            if len(set(list(p))-set(list(cand)))==0:
                flag = 0
                break
        if flag:
            q = [""]*m
            for j in i:
                for k in range(m):
                    q[k]+=("-"+arr[k][j])
            if len(set(q)) == m:
                key +=[cand]
    return len(key)

arr=[["b","2","a","a","b"],["b","2","7","1","b"],["1","0","a","a","8"],["7","5","a","a","9"],["3","0","a","f","9"]]
print(solution(arr))

카카오/2019 블라인드/후보키.py


count2=0
count=1
print("prime between 1--1000: ")
while count<2:
 for loop in range(2,1000):
  j=int(loop**0.5)
  while loop % j !=0:
  	j-=1
  if j==1:
       print("%3d " %loop, end='')
       count2+=1
       if count2 % 16==0:
         print('')
 count+=1
print(end='\n')
print("total number: "+str(count2))