import os
import numpy as np
import cv2
import scipy.io as sio
from math import cos, sin
from imutils import face_utils

def get_list_from_filenames(file_path):
    with open(file_path) as f:
        lines = f.read().splitlines()
    return lines

def normalize_landmark_point(original_point, image_size):
    '''
    original_point: (x, y)
    image_size: (W, H)
    '''
    x, y = original_point
    # x -= image_size[0] // 2
    # y -= image_size[1] // 2
    x /= image_size[0]
    y /= image_size[1]
    return [x, y]

def unnormalize_landmark_point(normalized_point, image_size, scale=[1,1]):
    '''
    normalized_point: (x, y)
    image_size: (W, H)
    '''
    x, y = normalized_point
    x *= image_size[0]
    y *= image_size[1]
    # x += image_size[0] // 2
    # y += image_size[1] // 2
    x *= scale[0]
    y *= scale[1]
    return [x, y]

def unnormalize_landmark(landmark, image_size):
    image_size = np.array(image_size)
    landmark = np.multiply(np.array(landmark), np.array(image_size))
    # landmark = landmark + image_size / 2
    return landmark

def normalize_landmark(landmark, image_size):
    image_size = np.array(image_size)
    # landmark = np.array(landmark) - image_size / 2
    landmark = np.divide(landmark, np.array(image_size))
    return landmark

def draw_landmark(img, landmark):
    im_width = img.shape[1]
    im_height = img.shape[0]
    img_size = (im_width, im_height)
    landmark = landmark.reshape((-1, 2))
    unnormalized_landmark = unnormalize_landmark(landmark, img_size)
    for i in range(unnormalized_landmark.shape[0]):
        img = cv2.circle(img, (int(unnormalized_landmark[i][0]), int(unnormalized_landmark[i][1])), 2, (0,255,0), 2)
    return img

def crop_loosely(shape, img, input_size, landmark=None):
    bbox, scale_x, scale_y = get_loosen_bbox(shape, img, input_size)
    crop_face = img[bbox[1]:bbox[3], bbox[0]:bbox[2]]
    crop_face = cv2.resize(crop_face, input_size)
    return crop_face

def get_loosen_bbox(shape, img, input_size):
    max_x = min(shape[2], img.shape[1])
    min_x = max(shape[0], 0)
    max_y = min(shape[3], img.shape[0])
    min_y = max(shape[1], 0)

    Lx = max_x - min_x
    Ly = max_y - min_y

    Lmax = int(max(Lx, Ly) * 2.0)

    delta = Lmax * 0.4

    center_x = (shape[2] + shape[0]) // 2
    center_y = (shape[3] + shape[1]) // 2
    start_x = int(center_x - delta)
    start_y = int(center_y - delta - 10)
    end_x = int(center_x + delta)
    end_y = int(center_y + delta - 10)

    if start_y < 0:
        start_y = 0
    if start_x < 0:
        start_x = 0
    if end_x > img.shape[1]:
        end_x = img.shape[1]
    if end_y > img.shape[0]:
        end_y = img.shape[0]

    scale_x = float(input_size[0]) / (end_x - start_x)
    scale_y = float(input_size[1]) / (end_y - start_y)
    return (start_x, start_y, end_x, end_y), scale_x, scale_y

def normalize_img_batch(images):
    image_batch = np.array(images, dtype=np.float32)
    image_batch /= 255.
    mean = np.array([0.485, 0.456, 0.406])
    std = np.array([0.229, 0.224, 0.225])
    image_batch[..., :] -= mean
    image_batch[..., :] /= std
    return image_batch

def square_padding(im, desired_size=800, return_padding=False):

    old_size = im.shape[:2]  # old_size is in (height, width) format

    ratio = float(desired_size) / max(old_size)
    new_size = tuple([int(x*ratio) for x in old_size])

    im = cv2.resize(im, (new_size[1], new_size[0]))

    delta_w = desired_size - new_size[1]
    delta_h = desired_size - new_size[0]
    top, bottom = delta_h // 2, delta_h - (delta_h // 2)
    left, right = delta_w // 2, delta_w - (delta_w // 2)

    color = [0, 0, 0]
    new_im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT,
                                value=color)

    if not return_padding:
        return new_im
    else:
        h, w = new_im.shape[:2]
        padding = (top / h, left / w, bottom / h, right / w)
        return new_im, padding


import sys
sys.stdin = open("3055in.txt",'r')

from collections import deque
R,C = map(int,input().split())
List = list(list( x for x in input()) for _ in range(R))
waters = deque([])
hedgehog = deque([])
dy = [-1,1,0,0]
dx = [0,0,-1,1]

for y in range(R):
    for x in range(C):
        if List[y][x] == "*":
            waters.append((y,x))
        elif List[y][x] == "S":
            hedgehog.append((y,x))

cnt = 0
def fillWaters(y,x):
    global visitedWater
    for i in range(4):
        checkY = y+dy[i]
        checkX = x+dx[i]
        if 0<=checkY<R and 0<=checkX<C and visitedWater[checkY][checkX] and (List[checkY][checkX]=="." or List[checkY][checkX]=="S"):
            List[checkY][checkX]="*"
            waters.append((checkY,checkX))

def goBeaver(y,x):

    pass

visitedWater = list(list(True for _ in range(C)) for _ in range(R))
visitedBeaver = list(list(True for _ in range(C)) for _ in range(R))
answer = 0
flag = 1
while flag:
    answer += 1
    for _ in range(len(waters)):
        Y,X = waters.popleft()
        fillWaters(Y,X)
    for _ in range(len(hedgehog)):
        Y,X = hedgehog.popleft()
        for i in range(4):
            newY = Y + dy[i]
            newX = X + dx[i]
            if 0<=newY<R and 0<=newX<C and visitedBeaver[newY][newX]:
                visitedBeaver[newY][newX] = False
                if List[newY][newX] == ".":
                    List[newY][newX] = "S"
                    hedgehog.append((newY,newX))
                if List[newY][newX] == "D":
                    hedgehog.append(("end"))
                    flag = 0
                    break

    if len(hedgehog):
        pass
    else:
        break
if hedgehog:
    print(answer)
else:
    print("KAKTUS")


import numpy as np
import scipy

import myfun as mf
import sys
import os

import matplotlib
matplotlib.use('Agg')

from matplotlib import gridspec, rc
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

rc('font',**{'family':'sans-serif','sans-serif':['Arial']})
rc('text',usetex=True)

#############################
####### Graphic loading #####
#############################
pngdir    = 'pngs'
figdir    = 'figs'

cell_nms  = ['hmsc_yellow','neutrophil_red','monocyte_blue','lightning_white',
             'lightning_orange', 'lightning_purple_flip','waddington']
cell_pics = [plt.imread('{0}/{1}.png'.format(pngdir,nm)) for nm in cell_nms]

#############################
###### Bifurcation loading ##
#############################
nb_dir = 'out/no_bifurc'
sn_dir = 'out/sn1'
pf_dir = 'out/pf_scale20'
datdirs = [nb_dir, sn_dir, pf_dir]
bif_vars = [np.load('{0}/bvars.npy'.format(ddir)) for ddir in datdirs]
gexps    = [np.load('{0}/gexp.npy'.format(ddir)) for ddir in datdirs]

#############################
##### Manual clustering #####
#############################
clust_poss_nb = np.array([[0.7,1.72],[2,1]]) # for "linear" (hill coeff 1)
clust_poss_sn = np.array([[0,3],[4,0]]) # for saddle node (hill coeff 2)
clust_poss_pf = np.array([[2,2],[0,4],[4,0]]) # for "pitchfork" (hill coeff 2)

clust_poss = [clust_poss_nb, clust_poss_sn, clust_poss_pf]

clust_dists = [np.array([np.linalg.norm(gexps[i][...,0:2]-clust_poss[i][j], axis=2)
                         for j in range(clust_poss[i].shape[0])])
                        for i in range(len(clust_poss))]

clust_labels      = [np.argmin(cd,axis=0) for cd in clust_dists]
clust_label_bools = [np.array(cl,dtype='bool') for cl in clust_labels]

#############################
###### The figure ###########
#############################
plt.style.use('./sty/one_col_fig.mplstyle')

frac = 2

marg_wd1 = 0.5
marg_wd2 = 1
marg_wd3 = 1.5
marg_ht  = 0.5

a_ht    = 8

b_wd    = 3
b_ht    = 3
leg_ht  = 1.5

t_ht    = 6
t_wd    = 12

# row heights
hts = np.array([
    t_ht,
    a_ht - t_ht,
    marg_ht,
    b_ht*2/3,
    b_ht*1/3,
    b_ht*1/3,
    b_ht*1/3,
    b_ht*2/3,
    leg_ht
])

wds = np.array([
    marg_wd1,
    b_wd - marg_wd1,
    marg_wd2,
    b_wd,
    marg_wd2,
    b_wd,
    marg_wd3,
    t_wd
])

hts = np.array(frac*hts,dtype = int)
wds = np.array(frac*wds,dtype = int)

rs = np.cumsum(hts) # starting rows
cs = np.cumsum(wds) # starting cols

nr = np.sum(hts)
nc = np.sum(wds)

wid = 11.4/2.54

ht  = wid*nr/nc

fig = plt.figure(figsize=(wid, ht), dpi=200)

gs   = gridspec.GridSpec(nr, nc)
axA   = plt.subplot(gs[   0 :rs[1]  , cs[0]:cs[5]])

axB0  = plt.subplot(gs[rs[3]:rs[6]  ,   0  :cs[1]])
axBL  = plt.subplot(gs[rs[7]:rs[8]  ,   0  :cs[5]])

axB1L   = plt.subplot(gs[rs[2]:rs[3],     0:cs[1]])
axB1ar1 = plt.subplot(gs[rs[3]:rs[4], cs[1]:cs[2]])
axB1a   = plt.subplot(gs[rs[2]:rs[4], cs[2]:cs[3]])
axB1ar2 = plt.subplot(gs[rs[2]:rs[4], cs[3]:cs[4]])
axB1b   = plt.subplot(gs[rs[2]:rs[4], cs[4]:cs[5]])

axB2L   = plt.subplot(gs[rs[6]:rs[7],     0:cs[1]])
axB2ar1 = plt.subplot(gs[rs[5]:rs[6], cs[1]:cs[2]])
axB2a   = plt.subplot(gs[rs[5]:rs[7], cs[2]:cs[3]])
axB2ar2 = plt.subplot(gs[rs[5]:rs[7], cs[3]:cs[4]])
axB2b   = plt.subplot(gs[rs[5]:rs[7], cs[4]:cs[5]])

#rsb  = np.hstack([[0],rs])
rsC = [0, rs[0],rs[4],rs[8]]
axC  = [plt.subplot( gs[rsC[i]:rsC[i+1],cs[6]:cs[7]], projection = '3d') for i in range(3)] # 3d time series

axAc = plt.subplot(gs[0:1,0:1])
axBc = plt.subplot(gs[rs[1]:rs[2],0:1])
axCc = plt.subplot(gs[0:1,cs[5]:cs[6]])

##########################
#### A: waddington #######
##########################
axA.set_xticks([])
axA.set_yticks([])
axA.imshow(cell_pics[6],extent=[-0.05,1.05,0.1,1.08],clip_on=False)
axA.set_xlim(0,1)
axA.set_ylim(0,1)
axA.axis('off')

#########################
#### B: cell pics #######
#########################
axB    = [axB0, axB1a, axB1b, axB2a, axB2b]
ctypes = [[0],[0,1],[1],[0,1,2],[1,2]]
ncs    = [[12],[5,5],[11],[4,3,4],[5,7]]
ncs    = [[70],[45,35],[75],[20,30,25],[35,40]] # ng = 10
ncs    = [[50],[25,30],[53],[15,25,20],[32,28]] # ng = 8
ncs    = [[35],[20,18],[37],[13,10,13],[21,20]] # ng = 7
ncs    = [[20],[12,10],[21],[7,6,8],[13,10]] # ng = 5
ncs    = [[14],[6,8],[14],[4,5,5],[7,7]] # ng = 4

sds    = [6,1,3,5,24]

ngrid = 4
gsz   = 1
imsz  = 0.6
jsz   = gsz-imsz
xmin     = -ngrid/2
xmax     =  ngrid/2
ymin     = -ngrid/2
ymax     =  ngrid/2

xx = np.arange(xmin+gsz/2, xmax, gsz)
yy = np.arange(ymin+gsz/2, ymax, gsz)

bbox_ctrs  = np.array([[[x,y] for x in xx] for y in yy]).reshape(len(xx)*len(yy),2)
bbox_dists = np.linalg.norm(bbox_ctrs,axis=1)
#bbox_dists = np.max(np.abs(bbox_ctrs),axis=1)
bbox_sort  = np.argsort(bbox_dists)
bbox_ctrs  = bbox_ctrs[bbox_sort]
lims       = np.hstack([np.unique(bbox_dists[bbox_sort],return_index=True)[1],len(bbox_dists)])

for i in range(len(axB)):
    np.random.seed(sds[i])
    ax     = axB[i]

    nc     = ncs[i]
    ctps   = ctypes[i]

    ctpsl  = np.hstack([ctps[j]*np.ones(nc[j],dtype='int') for j in range(len(nc))])
    np.random.shuffle(ctpsl)
    nctot  = ctpsl.shape[0]

    nplttd = 0

    for j in range(len(lims)-1):

        ctrs = bbox_ctrs[lims[j]:lims[j+1]]
        nrem = nctot - nplttd

        if nrem <= 0:
            break

        nims   = min(len(ctrs), nrem)
        imctrs = ctrs[np.random.choice(len(ctrs),nims,replace=False)]

        for k in range(nims):
            x0,y0 = imctrs[k] - gsz/2 + np.random.uniform(0,jsz,2)
            ax.imshow(cell_pics[ctpsl[nplttd+k]], extent=[x0,x0+imsz,y0,y0+imsz])
        nplttd += nims

    ax.set_xlim(xmin, xmax)
    ax.set_ylim(ymin, ymax)
    ax.axis('off')

############################
###### B : legend ##########
############################

# legends
labs = ['pluripotent','external stimuli','differentiated A', 'differentiated B']
pics = [cell_pics[i] for i in [0,3,1,2]] #cell_pics[3::-1]

axBL.axis('off')
axBL.set_xticks([])
axBL.set_yticks([])
npics = len(pics)

xmax = 21
ymax = 5
axBL.set_xlim(0,xmax)
axBL.set_ylim(0,ymax)

bbox = axBL.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
aspect_ratio = bbox.width / bbox.height

xmarg1 = 0.25
xmarg2 = 0.25
imwd   = 1
imspcx = 1
xmarg3 = 0

ymarg1 = 0
ymarg2 = 0.1
ymarg3 = 0.75
ymarg4 = 0.1
imht   = imwd*1.7 #aspect_ratio #2.5 #imwd*aspect_ratio
imspcy = (ymax - (ymarg1 + ymarg2 + ymarg3 + ymarg4 + imht*2)) / 1

rect = mpatches.FancyBboxPatch((xmarg1, ymarg1),
                               xmax-xmarg3-xmarg1, ymax-ymarg3-ymarg1,
                               facecolor='white',edgecolor='k',clip_on=False,linewidth=0.1,
                               boxstyle=mpatches.BoxStyle("Round",pad=0.5),zorder=0)

valigns=['center']*npics
#x0 = xmarg1 + xmarg2
#y0 = ymarg1 + ymarg2 + (imht + imspcy)*np.arange(npics)
x0 = xmarg1+xmarg2+np.array([0,0,11,11])
y0 = ymarg1 + ymarg2 + (imht + imspcy)*np.array([1,0,1,0])
for i in range(npics):
    axBL.imshow(pics[i],clip_on=True, extent = [x0[i],x0[i]+imwd,y0[i],y0[i]+imht],zorder=1,
                aspect='auto',origin='upper')
    axBL.text(s=labs[i],x=x0[i]+imsz+imspcx, y=y0[i]+imht/2,fontsize=6,verticalalignment=valigns[i],zorder=1)

axBL.add_artist(rect)

axBL.set_zorder(0)

############################
### B : top / bottom annotations #####
############################

txts = ['saddle node\nbifurcation', 'pitchfork\nbifurcation']
txts = ['one-to-one\nfate change', 'one-to-many\nfate change']
pics = cell_pics[4:6]
txtx = [1.1,1]
txty = [1,0.3]
valigns = ['top','bottom']
lightx0 = [1.15,1.45]
lighty0 = [-0.17,1.3]
lightsz = 0.4
axs = [axB1L, axB2L]

for i in range(len(axs)):
    # text
    ax = axs[i]
    ax.text(s=txts[i],x=txtx[i],y=txty[i],fontsize=6,verticalalignment=valigns[i],horizontalalignment='center')

    # lightning
    #tr = transforms.Affine2D().rotate_deg(180)
    ax.imshow(pics[i],clip_on=False, extent=[lightx0[i],lightx0[i]+lightsz,lighty0[i],lighty0[i]+lightsz])

    ax.set_xlim(0,1)
    ax.set_ylim(0,1)

    ax.axis('off')

######################################
######## middle arrows ###############
######################################
# first arrows
xs  = [0,0,0,0]
ys  = [0.5,0.5,0.5,0.5]
dxs = [1, 1,1,1]
dys = [0.3,-0.3,0,0]
axs = [axB1ar1, axB2ar1, axB1ar2, axB2ar2]
for i in range(len(axs)):
    ax = axs[i]
    ax.annotate("", xy=(xs[i]++dxs[i], ys[i]+dys[i]), xytext=(xs[i], ys[i]),
                arrowprops=dict(headwidth=3, headlength=2, width=0.5, fc='black', clip_on=False), clip_on=False)

    ax.axis('off')
    ax.set_zorder(1)

###########################
##### C: 3d bifurcations ##
###########################

fs = 6
axs = [0,0,0]
cols = ['goldenrod','brown','purple']

labs = ['pluripotent','lineage 1', 'lineage 2']
ms = np.array(['o','s','v'])

#gs.update(hspace=-0.89)

for ii in range(3):
    ax = axC[ii]
    ax.set_aspect('auto')
    ax.set_box_aspect((2.5,1,1))

    xtit_col = 'white' if ii > 0 else 'black'

    gexp = gexps[ii]
    taus = bif_vars[ii]
    clust_label_bool = clust_label_bools[ii]
    clust_label = clust_labels[ii]
    ntau,ncells,ngenes = gexp.shape

    for t in range(ntau):

        for j in range(clust_poss[ii].shape[0]):
            cidxs = np.where(clust_label[t]==j)[0]
            ts = taus[t]*np.ones(cidxs.shape[0])
            ax.scatter(ts, gexp[t,cidxs,0], gexp[t,cidxs,1],
                       s=4, edgecolor=cols[j], facecolor='none',linewidth=0.5,clip_on=False)

    ax.set_ylabel('gene i', fontsize = fs, labelpad=-19.5)
    ax.set_zlabel('gene j', fontsize=fs,labelpad=-19.5)

    #ax.view_init(5, 290)
    ax.view_init(-30, 255)

    ax.tick_params(axis='z',labelsize=fs)

    ax.set_xticks(np.linspace(taus[0],taus[-1],10))
    ax.set_xticklabels([])
    ax.set_yticklabels([])
    ax.set_zticklabels([])

    mf.set_axs_fontsize(ax,fs)
    ax.margins(0)
    ax.autoscale_view('tight')
    ax.dist=5.5
    if ii == 0:
        ax.set_xlabel('external stimuli',labelpad=-19,color=xtit_col)

    ax.patch.set_alpha(0)

####### captions #######
cap_fs = 11
axAc.text(s='A',x=0,y=2,fontsize=cap_fs,verticalalignment='top',horizontalalignment='left')
axAc.axis('off')

axBc.text(s='B',x=0,y=0,fontsize=cap_fs,verticalalignment='top',horizontalalignment='left')
axBc.axis('off')

axCc.text(s='C',x=1.25,y=2,fontsize=cap_fs,verticalalignment='top',horizontalalignment='right')
axCc.axis('off')

os.makedirs(figdir, exist_ok=True)
plt.savefig('{0}/fig1_dev_dyn.pdf'.format(figdir), bbox_inches='tight')


class Solution(object):
    def myPow(self, x, n):
        """
        :type x: float
        :type n: int
        :rtype: float
        """
        if abs(x) < 0.000000001 or x ==1:
            return x
        if n ==0:
            return 1
        if n == 1:
            return  x
        # if n < 0:
        #     return  1.0/self.myPowPositiveN(x,-n)
        # return  self.myPowPositiveN(x,n)
        if n < 0:
            return  1.0/self.myPow3(x,-n)
        return  self.myPow3(x,n)

    def myPowPositiveN(self,x,posiN):

        res = x
        #ra = (i for i in range(1,posiN))
        j = 1
        while j<posiN :
            res *=x
            j+=1
            if abs(res) <0.000000001:
                return 0
        return  res
    # 输入的n是正整数
    def myPowDiv(self,x,n):
        if n <= 0:
            return 1
        if n ==1:
            return x
        if n == 2:
            return x*x
        left = self.myPowDiv(x,n//2)
        right =self.myPowDiv(x,n-n//2)
        return  left*right

    '''
    这里根据位来计算。时间复杂度是log(N)
    '''
    def myPow3(self,x,n):
        base = x
        ans = 1
        while n > 0:
            bi = n &1
            if bi == 1:
                ans *= base
            base *=base
            n>>=1
        return  ans

if __name__ == '__main__':

    so = Solution()
    print(so.myPow(8.88023,3))


f = open("25.txt", "r")
f2 = open("25mini.txt", "r")
inputs = [i for i in f.read().split("\n")]
miniinputs = [i for i in f2.read().split("\n")]

#Part 1
def stepDir(inputs, d):
    sym = ">" if d == (0, 1) else "v"
    moved = {(i, j) for i in range(len(inputs)) for j in range(len(inputs[0]))
        if inputs[i][j] == sym and inputs[(i+d[0])%len(inputs)][(j+d[1])%len(inputs[0])] == "."}
    for i, j in moved:
        inputs[i][j] = "."
        inputs[(i+d[0])%len(inputs)][(j+d[1])%len(inputs[0])] = sym
    return inputs, len(moved)

def step(inputs):
    inputs, move1 = stepDir(inputs, (0, 1)) #east steps
    inputs, move2 = stepDir(inputs, (1, 0)) #south steps
    return inputs, move1+move2

def part1(inputs):
    inputs = [[j for j in i] for i in inputs]
    i = 0
    while True:
        i += 1
        inputs, moved = step(inputs)
        if moved == 0:
            return i

print("REAL PART 1: ", part1(inputs))
print("MINI PART 1: ", part1(miniinputs))


def main():
    input = open("input.txt").readlines()

    part1(input)
    part2(input)

def part1(input):
    VISITED_SET = set()

    head_coordinates = (0, 0)
    tail_coordinates = (0, 0)

    VISITED_SET.add(tail_coordinates)

    for i in input:
        direction, steps = i.split(' ')

        for x in range(int(steps)):
            head_coordinates, tail_coordinates, _ = \
                get_new_position(*head_coordinates, *tail_coordinates,
                                 direction)

            VISITED_SET.add(tail_coordinates)

    print("Part 1:", len(VISITED_SET))

def part2(input):
    VISITED_SET = set()
    NUM_LINKS = 10

    position = [(0, 0) for x in range(NUM_LINKS)]

    VISITED_SET.add(position[-1])

    for i in input:
        direction, steps = i.split(' ')

        for x in range(int(steps)):
            is_head = True
            for y in range(NUM_LINKS - 1):
                front_position = position[y]
                back_position = position[y + 1]

                position[y], position[y + 1], has_changed = \
                    get_new_position(
                        *front_position, *back_position,
                        direction, is_head
                    )

                if not has_changed:
                    break

                is_head = False

            VISITED_SET.add(position[-1])

    print("Part 2:", len(VISITED_SET))

def get_new_position(head_x_coord, head_y_coord, tail_x_coord,
                     tail_y_coord, direction, is_head=True):
    if not is_head:
        new_head = (head_x_coord, head_y_coord)
    elif direction == "R":
        new_head = (head_x_coord + 1, head_y_coord)
    elif direction == "L":
        new_head = (head_x_coord - 1, head_y_coord)
    elif direction == "U":
        new_head = (head_x_coord, head_y_coord + 1)
    elif direction == "D":
        new_head = (head_x_coord, head_y_coord - 1)

    new_tail = check_move(*new_head, tail_x_coord, tail_y_coord)

    has_changed = False if new_tail == (tail_x_coord, tail_y_coord) else True

    return new_head, new_tail, has_changed

def check_move(head_x_coord, head_y_coord, tail_x_coord, tail_y_coord):
    if abs(head_x_coord - tail_x_coord) <= 1 \
            and abs(head_y_coord - tail_y_coord) <= 1:
        new_tail = (tail_x_coord, tail_y_coord)
    else:
        if head_y_coord == tail_y_coord:
            new_tail_x = (head_x_coord + tail_x_coord) // 2
            new_tail = (new_tail_x, tail_y_coord)
        elif head_x_coord == tail_x_coord:
            new_tail_y = (head_y_coord + tail_y_coord) // 2
            new_tail = (tail_x_coord, new_tail_y)
        else:
            new_tail_x = tail_x_coord + 1 if head_x_coord >\
                tail_x_coord else tail_x_coord - 1
            new_tail_y = tail_y_coord + 1 if head_y_coord >\
                tail_y_coord else tail_y_coord - 1
            new_tail = (new_tail_x, new_tail_y)

    return new_tail

if __name__ == "__main__":
    main()


#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time : 2021/7/31 19:06
# @Author : apple
# @Software: PyCharm
import requests
import os
import pytest
from requests_toolbelt import MultipartEncoder
from case.common_login_function import CloudLoginClass
from case.login.func_login import login
from case.login import loginDemo

@pytest.fixture(scope="module")
def login_fix():
    '''自定义一个前置的操作'''
    print("先登陆")
    s = requests.session()
    login(s)
    return s

@pytest.fixture(scope="function")
def unlogin_fix():
    '''自定义一个前置的操作'''
    print("不登陆")
    s = requests.session()
    s.headers.update({"Authorization": "Token f4b9a1dffbf525ecc93f8c80035c60fa546d5xxx"})
    return s

@pytest.fixture(scope="function")
def add_testdata():
    print("新增测试数据")

# 练习pytest的fixture,级别不同，只需要修改scope的
# `"function"``
#    `"function"``     (default), ``"class"``, ``"module"``, ``"package"`` or ``"session"``.
'''
登录的loginfixSession
'''
@pytest.fixture(scope='session')
def loginfixSession():
    s = requests.session()
    cloudloginclass = CloudLoginClass(s)
    ressession=cloudloginclass.loginFun()
    print ( '执行了cloud登录' )
    return ressession

# 命令行可设置不同的host参数
def pytest_addoption(parser):
    parser.addoption(
        "--cmdhost", action="store", default="http://222.128.6.177:8666", help="my option: type1 or type2"
    )
# autouse默认打开
@pytest.fixture(scope="session", autouse=True)
def host(request):
    '''获取命令行参数'''
    # 获取命令行参数给到环境变量
    os.environ['cloudHost'] = request.config.getoption("--cmdhost")
    print("当前用例运行测试环境22:%s"%os.environ["host"])

# 教师云上传文件[前置]
@pytest.fixture(scope="function")
def doUpload(loginfixSession):
    ss = loginfixSession
    url=os.environ['cloudHost']+'/cloudApi/fileUpload/doUpload'
    m= MultipartEncoder(
        fields=[('bussCode', 'bookCatalog'),
                ('file', (
                'zxz.png', open(r'C:\Users\admin\PycharmProjects\api_Project_Pytest\case\ziyuanguanli\0_pic.png', 'rb'),
                'image/png'))
                ]
    )
    res =ss.post(url,data=m,headers={'Content-Type':m.content_type})
    var2 = res.json()["data"]["resourceId"]
    print(var2)
    return var2


# 완전 이진 트리 (BOJ 9934)
import sys
sys.setrecursionlimit(10**6)
In = sys.stdin.readline

k = int(In())
buildings = list(map(str, In().rstrip().split()))
tree = [[] for _ in range(k)]

def infix_to_tree(left: int, right: int, lv: int):
    if left == right:
        tree[lv].append(buildings[left])
        return

    mid = (right+left)//2
    tree[lv].append(buildings[mid])
    infix_to_tree(left, mid-1, lv+1)
    infix_to_tree(mid+1, right, lv+1)

def main():
    infix_to_tree(0, 2**k-2, 0)
    for level in tree:
        print(' '.join(level))

if __name__ == "__main__":
    main()


"""
bruh
"""

import discord
import re # Regex for dynamic bruh emoji acceptance

def readToken():
    with open("TOKEN", 'r') as f:
        return f.read()

TOKEN = readToken()

class Bruh(discord.Client):
    voice_handles = {}

    def setTraining():
        pass

    # Python can't deal with emojis, convert to unicode codes
    def convertToUnicode(self, emoji):
        return emoji.encode('unicode-escape').decode('utf-8')

    def isValidMessage(self, message):

        # Plain bruh
        if message == "bruh":
            return True

        # Dynamic bruhs (only 'bruh', ':bruh:', and ' ' are allowed)
        if message != message.lstrip(" "): # No leading whitespace
            return False
        if "bruhbruh" in message: # No double bruh
            return False
        if "     " in message: # No more than 4 spaces in a row
            return False

        message = re.sub("<:bruh:\d+>", "", message) # Bruh emoji is allowed
        message = message.replace("bruh", "") # Bruh is allowed
        message = message.replace(" ", "") # Single space allowed
        if message == "":
            return True

        return False # DESTROY

    def isValidReaction(self, reaction):

        reactions = reaction.message.reactions

        # A default unicode emoji
        if not reaction.custom_emoji:
            # Allow a custom bruh emoji to be before the unicode bruhs
            reactionOffset = 1
            if reactions[0].custom_emoji:
                reactionOffset = 2

            # bruh only
            regional_indicator_bruh = [
                '\U0001f1e7', #B
                '\U0001f1f7', #R
                '\U0001f1fa', #U
                '\U0001f1ed'] #H

            emoji = self.convertToUnicode(reaction.emoji)
            properEmoji = self.convertToUnicode(regional_indicator_bruh[(len(reactions) % 4) - reactionOffset])

            if emoji == properEmoji: # Valid reaction
                return True

            return False # Invalid

        # A custom bruh emoji
        if len(reactions) == 1 or len(reactions) == 5: # Allow a unicode bruh sequence
            validEmojiNames = [                        # to be followed by a custom bruh
                'bruh']
            valid = False
            for validEmojiName in validEmojiNames:

                if reaction.emoji.name == validEmojiName:
                    return True

        return False

    async def validateMessage(self, message):
        print("\"" + message.content + "\"")
        print("message sent by: " + message.author.name + " (" + message.author.nick + ")")
        if self.isValidMessage(message.content):
            print("valid")
            return

        # Invalid message. Delete
        print("invalid")
        channel = message.channel
        await message.delete()

    async def validateReaction(self, reaction, user):
        print("\"" + self.convertToUnicode(reaction.emoji) + "\"")
        print("reaction sent by: " + user.name + " (" + user.display_name + ")")
        if self.isValidReaction(reaction):
            print("valid")
            return

        # Invalid reaction. Delete
        print("invalid")
        await reaction.remove(user)

    # Sent messages
    async def on_message(self, message):

        if message.author == self.user:
            return

        if message.channel.name != "bruh":
            return

        await self.validateMessage(message)

    # Edits
    async def on_message_edit(self, before, after):
        await self.validateMessage(after)

    # Reactions
    async def on_reaction_add(self, reaction, user):
        await self.validateReaction(reaction, user)

    # Voice
    async def on_voice_state_update(self, before, after):
        # prevent recursion
        if after == self.user:
            return

        channel = after.voice.voice_channel
        if type(channel) == type(None):
            # User left channel
            channel = before.voice.voice_channel
        elif channel.name == "bruh":
            vc = await self.join_voice_channel(channel)
            self.voice_handles[channel.id] = vc
            return

        # Check if channel empty
        if len(channel.voice_members) <= 1:
            # channel is empty
            handle = self.voice_handles[channel.id]
            await handle.disconnect()

    async def on_ready(self):
        print("ready")

if __name__ == "__main__":
    client = Bruh()

    client.run(TOKEN)


import os
import logging
from datetime import datetime
import importlib
import json
import uuid
import multiprocessing
import queue
import sys
from io import TextIOWrapper
import traceback
from typing import Callable, Any, NoReturn

class PluginHookManager:
    def __init__(self) -> None:
        self.hooktable: dict[str, list[dict[str,
                                            Callable[[Any, Any], Any] | int]]] = {}
        self.logger: logging.Logger = logging.getLogger("plugin-hook")

    def create(self, hook_name: str = None, default_handler: Callable[[Any, Any], Any] = None) -> None:
        if hook_name is None:
            self.logger.warning("No hook name was given. Ignored...")
            return
        if hook_name in self.hooktable:
            self.logger.warning("Hook name had been taken. Ignored...")
            return
        self.hooktable[hook_name] = []
        if default_handler is not None:
            self.hooktable[hook_name].append(
                {"function": default_handler, "priority": 0})
        self.logger.debug(
            "Creating hook \"%s\" had successfully ended.", hook_name)
        return

    def publish(self, hook_name: str = None, args: tuple = None):
        if hook_name is None:
            self.logger.warning("No hook name was given. Ignored...")
            return
        if not hook_name in self.hooktable:
            self.logger.warning("Invaild hook name was given. Ignored...")
            return
        if args is None:
            self.logger.warning("No arguments were given. Setting empty...")
            args = tuple()
        for subscriber in self.hooktable[hook_name]:
            try:
                ret = subscriber['function'](*args)
                if ret == 1:
                    break
            except Exception as e:
                self.logger.exception(e)
                return
        self.logger.debug(
            "Publishing hook \"%s\" had successfully ended.", hook_name)
        return

    def register(self, hook_name: str = None, func: Callable[[Any, Any], Any] = None, priority: int = 1):
        if hook_name is None:
            self.logger.warning("No hook name was given. Ignored...")
            return
        if func is None:
            self.logger.warning("No function was given. Ignored...")
            return
        i = 0
        while True:
            if i == len(self.hooktable[hook_name]):
                self.hooktable[hook_name].append(
                    {"function": func, "priority": priority})
                break
            if priority >= self.hooktable[hook_name][i]['priority']:
                self.hooktable[hook_name] = self.hooktable[hook_name][:i] + [
                    {"function": func, "priority": priority}] + self.hooktable[hook_name][i:]
                break
            i += 1
        self.logger.debug(
            "Registering hook \"%s\" had successfully ended.", hook_name)
        return

def CRASH(message: str = "*NO REASON*") -> NoReturn:
    sys.stderr.flush()
    sys.stderr.write("\033[91m===========================================\n")
    sys.stderr.write("CRITICAL ERROR OCCURRED!\n")
    sys.stderr.write("===========================================\n")
    sys.stderr.write("THIS PROGRAM HAD OCCURRED A CRITICAL ERROR.\n")
    sys.stderr.write("NO HANDLER (FOUND) TO HANDLE THIS ERROR.\n")
    sys.stderr.write("===========================================\n")
    sys.stderr.write("CRASH REASON:\n")
    sys.stderr.write(message + "\n")
    sys.stderr.write("===========================================\033[0m\n")
    sys.stderr.flush()
    raise Exception(globals())
    sys.exit(-1)

class WorkspaceManager:
    def __init__(self, pluginpath: str = "./plugins/", logpath: str = "./logs/") -> None:
        self.plugin_path: str = pluginpath
        self.log_path: str = logpath
        try:
            if not os.path.exists(self.plugin_path):
                os.mkdir(self.plugin_path)
            if not os.path.exists(self.log_path):
                os.mkdir(self.log_path)
        except Exception as e:
            CRASH("CANNOT CREATE WORKSPACE FOLDERS")

class LoggingManager:
    def __init__(self, filepath="./logs/", level=logging.INFO) -> None:
        self.filename = filepath+datetime.now().strftime("%Y-%m-%d %H-%M-%S")+".log"
        self.level = level
        self.init()
        self.logger = logging.getLogger("logging-mgr")

    def init(self) -> None:
        try:
            filehandler = logging.FileHandler(
                filename=self.filename, mode="w+", encoding="UTF-8")
            logging.basicConfig(handlers=[logging.StreamHandler(), filehandler], force=True,
                                level=self.level, format='[%(levelname)s][%(asctime)s][%(name)s]%(message)s')
        except Exception as e:
            CRASH("LOGGING-MGR FAILED TO INIT LOGGING MOUDLE.")

class ConfigManager:
    def __init__(self, config_file: str = "./config.json") -> None:
        self.logger: logging.Logger = logging.getLogger("config-mgr")
        self.logger.info("Initialing Config Manager Subsystem.")
        self.file: str = config_file
        self.config: dict[str, dict | str | int | float] = {}
        self.init()
        self.logger.info("Initialed Config Manager Subsystem.")

    def init(self) -> None:
        if not os.path.exists(self.file):
            self.logger.warning(
                "Config file \"%s\" doesn't exist! Creating...", self.file)
            fp: TextIOWrapper = open(self.file, 'x')
            fp.close()
        fp: TextIOWrapper = open(self.file, "r+", encoding="UTF-8")
        if fp.read() == "":
            self.config: dict = {
                "pypluging": {
                    "version": "a0.0.1"
                },
                "plugin": {
                    "permission": [],
                    "safemode": False,
                    "default_permission": 1
                },
                "plugin-data": {}
            }
            json.dump(self.config, fp)
        fp.close()

    def save(self) -> None:
        try:
            fp: TextIOWrapper = open(self.file, "r+", encoding="UTF-8")
            json.dump(self.config, fp)
            fp.close()
        except Exception as e:
            self.logger.error(
                "Failed to save config file. Trying reinitialize the file.")
            self.init()
        self.logger.info("Saved Config File.")

    def load(self) -> None:
        try:
            fp: TextIOWrapper = open(self.file, "r+", encoding="UTF-8")
            self.config = json.load(fp)
            fp.close()
        except Exception as e:
            self.logger.error(
                "Failed to load config file. Trying reinitialize the file.")
            self.init()
        self.logger.info("Loaded Config File.")

    def get(self) -> dict:
        return self.config

def initPlugins():
    global data
    logger = logging.getLogger("init")
    plugin_list = os.listdir("./plugins/")
    plugin_priored = []
    i = 0
    while True:
        if i == len(plugin_list):
            break
        if plugin_list[i].endswith(".py"):
            if not plugin_list[i] in data["config"]["plugins"]:
                logging.info("new plugin find! Recording to config...")
                data['config']['plugins'][plugin_list[i]] = 0
                fp = open("./config.json", "w+", encoding="UTF-8")
                json.dump(data["config"], fp)
                fp.close()
            k = 0
            while True:
                priority = data["config"]["plugins"][plugin_list[i]]
                if k == len(plugin_priored):
                    plugin_priored.append(
                        {"name": plugin_list[i], "priority": priority})
                    break
                if priority >= plugin_priored[k]['priority']:
                    plugin_priored = plugin_priored[:k] + [
                        {"name": plugin_list[i], "priority":priority}] + plugin_priored[k:]
                    break
                k += 1
        else:
            logger.debug("passed file %s", plugin_list[i])
        i += 1
    for i in range(len(plugin_priored)):
        if data["config"]["plugins"][plugin_priored[i]["name"]] > 0:
            logger.info("trying to load plugin \"%s\"...",
                        plugin_priored[i]["name"][:plugin_priored[i]["name"].find(".py")])
            try:
                plugin_object = importlib.import_module(
                    '.'+plugin_priored[i]["name"][:plugin_priored[i]["name"].find(".py")], package='plugins')
                info = plugin_object.GetPluginInfo()
                data['plugins'][info['namespace']] = info
                if 'onInit' in info["entrypoints"]:
                    info["entrypoints"]['onInit'](data)
            except Exception as e:
                logger.debug(
                    "failed to load plugin using importlib, trying exec")
                try:
                    plugin_global = {}
                    plugin_fp = open(
                        "./plugins/"+plugin_priored[i]["name"], "r", encoding="UTF-8")
                    exec(plugin_fp.read(), plugin_global)
                    info = plugin_global["GetPluginInfo"]()
                    data['plugins'][info['namespace']] = info
                    if 'onInit' in info["entrypoints"]:
                        info["entrypoints"]['onInit'](data)
                except Exception as e:
                    logger.exception(e)
                    logger.info("plugin \"%s\" failed to load.",
                                plugin_priored[i]["name"][:plugin_priored[i]["name"].find(".py")])
                    continue
            logger.info("plugin \"%s\" loaded successfully.",
                        plugin_priored[i]["name"][:plugin_priored[i]["name"].find(".py")])

if __name__ == "__main__":
    workspacemgr = WorkspaceManager()
    logmgr = LoggingManager()
    configmgr = ConfigManager()
    CRASH("no functions running at the end")


import numpy as np
import pandas as pd
import argparse
from datetime import datetime
import matplotlib.pyplot as plt
from statistics import mean
from collections import defaultdict
from pprint import pprint
import warnings
import math
from matplotlib.backends.backend_pdf import PdfPages

def main():
    parser = argparse.ArgumentParser(description="A program for processing the trade raw files")
    parser.add_argument('-f', '--trading_file', type=str, required=True,
                        help='Please provide the input raw trading CSV file which is needed to be processed'
                             'Headers should be as first row of the file, and data should be in th')
    parser.add_argument('-re', '--reporter', type=str, required=True,
                        help='Please provide the reporter country name')
    parser.add_argument('-pa', '--partner', type=str, required=True,
                        help='Please provide the partner country name')
    parser.add_argument('-flow', '--flow', type=str, required=True,
                        help='Please provide the flow')
    #parser.add_argument('-y', '--year', type=int, nargs='?', default=2019,
                        #help='Please provide the year, default value is 2019')
    #parser.add_argument('-cat', '--category_id', type=int, required=True,
                        #help='Please provide the two-digit category id (for example 61)')
    parser.add_argument('-o', '--output_file', type=str, required=True,
                        help='Please provide the output file name where you want to store the processed file')

    args = parser.parse_args()

    delivarable2(args.reporter, args.partner, args.flow, args.trading_file, args.output_file)

def delivarable2(re, pa, flow, trading, out, k=20):
    #Import Data
    data = pd.read_csv(trading)
    del data['Unnamed: 0']

    #dataimport = data[data['FLOW']=="export"]

    datareq1=data[data['DECLARANT']== re]
    datareq2=datareq1[datareq1['PARTNER']== pa]
    #datareq3=datareq2[datareq2['check']== cat]
    datareq3 = datareq2[datareq2['FLOW']==flow]
    #datareq4=datareq3[(datareq3['PERIOD']/100).astype(int)== 2015]
    #datareq5 = datareq4.sort_values(by = 'VALUE_IN_EUROS', ascending=False)
    datareq6=datareq3.groupby('PRODUCT_ID', as_index=False, sort=False).agg({'VALUE_IN_EUROS':'sum', 'PERIOD':'first'})

    df = pd.DataFrame(datareq6['PRODUCT_ID'], columns=['PRODUCT_ID','Year 2015','Year 2016','Year 2017','Year 2018', 'Year 2019'])
    for ind in range(20):
        if(int(datareq6['PERIOD'][ind]/100)==2015):
            df['Year 2015'][ind]=datareq6['VALUE_IN_EUROS'][ind]
        else:
            if(int(datareq6['PERIOD'][ind]/100)==2016):
                df['Year 2016'][ind]=datareq6['VALUE_IN_EUROS'][ind]
            if(int(datareq6['PERIOD'][ind]/100)==2017):
                df['Year 2017'][ind]=datareq6['VALUE_IN_EUROS'][ind]
            if(int(datareq6['PERIOD'][ind]/100)==2018):
                df['Year 2018'][ind]=datareq6['VALUE_IN_EUROS'][ind]
            if(int(datareq6['PERIOD'][ind]/100)==2019):
                df['Year 2019'][ind]=datareq6['VALUE_IN_EUROS'][ind]

    df['Year 2015']=df['Year 2015'].fillna(0)
    df['Year 2016']=df['Year 2016'].fillna(0)
    df['Year 2017']=df['Year 2017'].fillna(0)
    df['Year 2018']=df['Year 2018'].fillna(0)
    df['Year 2019']=df['Year 2019'].fillna(0)
    df_final=df.head(20)
    print(df_final)
    fig, ax =plt.subplots(figsize=(21,6))
    ax.axis('tight')
    ax.axis('off')
    the_table = ax.table(cellText=df_final.values,colLabels=df_final.columns,loc='center')
    pp = PdfPages(out)
    pp.savefig(fig, bbox_inches='tight')
    pp.close()

if __name__ == '__main__':
    main()


import os
from tweepy import OAuthHandler, API, Cursor
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.probability import FreqDist
from nltk.stem import WordNetLemmatizer as wnl
from string import punctuation
from re import sub

consumer_key = os.getenv('translation_consumer_key')
consumer_secret = os.getenv('translation_consumer_secret')
access_token = os.getenv('translation_access_token')
access_token_secret = os.getenv('translation_access_token_secret')

# use OAuthHandler class to handle authentication (no callback url needed)
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
# API takes in authenication handler to be used; allows access to entire twitter restful api methods
api = API(auth)

# dictionary containing last 5 tweets of each candidate
accounts = {
    'JoeBiden': [],
    'BernieSanders': [],
    'realDonaldTrump': [],
    'MikeBloomberg': [],
    'ElizabethWarren': [],
    'TulsiGabbard': [],
    'AndrewYang': []
}

def get_tweets() -> list:
    """From list of accounts, get their 5 most recent tweets."""
    # iterate through list of accounts
    for account in accounts:
        # get each account's timeline of the last 5 tweets
        for status in Cursor(api.user_timeline,id=account, tweet_mode="extended").items(5):
            # check is status is a retweet, otherwise full text will be truncated
            if hasattr(status, 'retweeted_status'):
                status = status.retweeted_status
            # get full text of each status
            status = status.full_text
            # remove http link at the end
            status = sub(r'https://t.co/\S+','', status)
            # add to list of tweets by account
            accounts[account].append(status)

    return accounts

# tokenize tweets using NLTK
def tokenize_tweets(accounts) -> list:
    """returns list of tokenized tweets of all users without stopword and punctuation tokens"""
    # create list to add tweets together
    all_tweets = []
    # iterate through each account
    for account in accounts:
        # get list of tweets from each account
        tweets = accounts[account]
        # iterate through tweets for each account
        for tweet in tweets:
            all_tweets.extend(word_tokenize(tweet))

    return all_tweets

def filter_tokens(tokens_list) -> list:
    """removes all stopsword and punctuation tokens from list of words"""
    filtered_tokens = []
    # create set of english stop words
    stop_words = set(stopwords.words('english'))
    # iterate though tokens list
    for token in tokens_list:
        # lemmatize (default pos is noun) and lowercase each token
        token = wnl().lemmatize(token).lower()
        # only add if it is not a stopword, punctuation, and longer than 3 chars
        if token not in stop_words and token not in punctuation and len(token) > 3:
            filtered_tokens.append(token)

    return filtered_tokens

def get_frequent_tokens() -> list:
    """returns list of top 5 frequently used tokens"""
    # populate accounts by get_tweets; tokenize all tweets into list of unfiltered_tokens
    unfiltered_list = tokenize_tweets(get_tweets())
    # filter list of tokens
    filtered_list = filter_tokens(unfiltered_list)
    # create an object of FreqDist and return top 5 words
    frequency_count = FreqDist(filtered_list).most_common(5)
    top5_tokens = []
    for word, frequency in frequency_count:
        # add only the word in tuple to return_list
        top5_tokens.append(word)

    return top5_tokens


import sys

#  약수가 존재하면 소수가 아님을 이용
m,n = map(int,sys.stdin.readline().split())
for i in range(m,n+1):
    if i == 1:
        continue
    for j in range(2, int(i**0.5)+1):
        if i %j ==0:
            break
    else:
        print(i)


"""Irondomo Protocol Client API, Python version.
Implements the IDP/Worker.
Author: Matteo Ferrabone <matteo.ferrabone@gmail.com>
"""

import logging

import zmq

from IronDomo import IDP

from IronDomo.IDPHelpers import dump
from IronDomo.IDPHelpers import Req

class IronDomoClient(object):
    """Irondomo Protocol Client API, Python version.
    """
    #broker = None
    #ctx = None
    #client = None
    #poller = None
    #timeout = 2500
    retries = 3
    verbose = True
    credentials = None

    def __init__(self, broker, verbose=False, credentials=None, identity=None, ctx=None, timeout = 2500):
        self.timeout = timeout
        self.client = None
        self.conncnt = 0
        self.broker = broker
        self.verbose = verbose
        self.identity = identity
        self.ctx = zmq.Context() if ctx == None else ctx
        self.poller = zmq.Poller()
        self.credentials = credentials
        logging.basicConfig(format="%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S",
                level=logging.INFO)
        self.reconnect_to_broker()

    def reconnect_to_broker(self):
        """Connect or reconnect to broker"""
        if self.client:
            self.poller.unregister(self.client.socket)
            self.client.close()
        self.client = Req(self.broker, ctx=self.ctx, identity="{0}_{1}".format(self.identity, self.conncnt))
        self.conncnt = self.conncnt + 1
        if (self.credentials is not None):
            self.client.setup_curve((self.credentials[1], self.credentials[2]), self.credentials[0])
        self.client.connect()
        self.poller.register(self.client.socket, zmq.POLLIN)
        if self.verbose:
            logging.info("I: connecting to broker at %s...", self.broker)

    def send(self, service, request):
        """Send request to broker and get reply by hook or crook.
        Takes ownership of request message and destroys it when sent.
        Returns the reply message or None if there was no reply.
        """
        if not isinstance(request, list):
            request = [request]
        request = [IDP.C_CLIENT, service] + request
        if self.verbose:
            logging.info("I: send request to '%s' service: ", service)
            dump(request)
        reply = None

        retries = self.retries
        while retries > 0:
            self.client.send(request)
            try:
                items = self.poller.poll(self.timeout)
            except KeyboardInterrupt:
                break # interrupted

            if items:
                msg = self.client.recv()
                if self.verbose:
                    logging.info("I: received reply:")
                    dump(msg)

                # Don't try to handle errors, just assert noisily
                assert len(msg) >= 3

                header = msg.pop(0)
                assert IDP.C_CLIENT == header

                reply_service = msg.pop(0)
                assert service == reply_service

                reply = msg
                break
            else:
                if retries:
                    logging.warn("W: no reply, reconnecting...")
                    self.reconnect_to_broker()
                else:
                    logging.warn("W: permanent error, abandoning")
                    break
                retries -= 1

        return reply

    def close(self):
        self.client.close()
        self.ctx.destroy()


#bases
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
import graphviz

#scikit learn
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, precision_score, confusion_matrix, classification_report
from sklearn.utils import shuffle

#trabalhando com 4 classes alvo
def seta_classe(df, coluna_ordem, coluna_classe):
    quartil_1 = df[coluna_ordem].quantile(q=0.25, interpolation='linear')
    quartil_2 = df[coluna_ordem].quantile(q=0.50, interpolation='linear')
    quartil_3 = df[coluna_ordem].quantile(q=0.75, interpolation='linear')
    quartil_4 = df[coluna_ordem].quantile(q=0.85, interpolation='linear')

    for _, row in df.iterrows():
        if row[coluna_ordem] >= 1 and row[coluna_ordem] <= quartil_1:
            row[coluna_classe] = 1
        elif row[coluna_ordem] > quartil_1 and row[coluna_ordem] <= quartil_2:
            row[coluna_classe] = 2
        elif row[coluna_ordem] > quartil_2 and row[coluna_ordem] <= quartil_3:
            row[coluna_classe] = 3
        elif row[coluna_ordem] > quartil_3 and row[coluna_ordem] <= quartil_4:
            row[coluna_classe] = 4

#trabalhando com 10 faixas para atributos contínuos
def seta_faixa(df, coluna_ordem, coluna_faixa):
    quartil_1 = df[coluna_ordem].quantile(q=0.1, interpolation='linear')
    quartil_2 = df[coluna_ordem].quantile(q=0.2, interpolation='linear')
    quartil_3 = df[coluna_ordem].quantile(q=0.3, interpolation='linear')
    quartil_4 = df[coluna_ordem].quantile(q=0.4, interpolation='linear')
    quartil_5 = df[coluna_ordem].quantile(q=0.5, interpolation='linear')
    quartil_6 = df[coluna_ordem].quantile(q=0.6, interpolation='linear')
    quartil_7 = df[coluna_ordem].quantile(q=0.7, interpolation='linear')
    quartil_8 = df[coluna_ordem].quantile(q=0.8, interpolation='linear')
    quartil_9 = df[coluna_ordem].quantile(q=0.9, interpolation='linear')

    for _, row in df.iterrows():
        if row[coluna_ordem] <= quartil_1:
            row[coluna_faixa] = 1
        elif row[coluna_ordem] > quartil_1 and row[coluna_ordem] <= quartil_2:
            row[coluna_faixa] = 2
        elif row[coluna_ordem] > quartil_2 and row[coluna_ordem] <= quartil_3:
            row[coluna_faixa] = 3
        elif row[coluna_ordem] > quartil_3 and row[coluna_ordem] <= quartil_4:
            row[coluna_faixa] = 4
        elif row[coluna_ordem] > quartil_4 and row[coluna_ordem] <= quartil_5:
            row[coluna_faixa] = 5
        elif row[coluna_ordem] > quartil_5 and row[coluna_ordem] <= quartil_6:
            row[coluna_faixa] = 6
        elif row[coluna_ordem] > quartil_6 and row[coluna_ordem] <= quartil_7:
            row[coluna_faixa] = 7
        elif row[coluna_ordem] > quartil_7 and row[coluna_ordem] <= quartil_8:
            row[coluna_faixa] = 8
        elif row[coluna_ordem] > quartil_8 and row[coluna_ordem] <= quartil_9:
            row[coluna_faixa] = 9
        elif row[coluna_ordem] > quartil_9:
            row[coluna_faixa] = 10

def analise_geral(df, rotulo, titulo):
    #alguns agrupamentos para visualização
    df_top_ano = df.groupby('cd_ano').agg({rotulo: [np.mean]})
    df_top_mes = df.groupby('cd_mes').agg({rotulo: [np.mean]})
    df_pes_ano = df.groupby('cd_ano').agg({'pesocargabruta': [np.sum]})
    df_pes_mes = df.groupby('cd_mes').agg({'pesocargabruta': [np.sum]})
    df_teu_ano = df.groupby('cd_ano').agg({'teu': [np.sum]})
    df_teu_mes = df.groupby('cd_mes').agg({'teu': [np.sum]})

    #graficos gerais
    fig, axes = plt.subplots(nrows=3, ncols=2)
    fig.suptitle(titulo + ' - Agrupamentos', fontsize=16)

    axes[0,0].set_title('Tempo vs Ano')
    axes[0,1].set_title('Tempo vs Mes')
    axes[1,0].set_title('Peso vs Ano')
    axes[1,1].set_title('Peso vs Mes')
    axes[2,0].set_title('TEU vs Ano')
    axes[2,1].set_title('TEU vs Mes')

    df_top_ano.plot(kind='bar', ax=axes[0,0], legend=False, color='cyan')
    df_top_mes.plot(kind='line', ax=axes[0,1], legend=False, color='blue')
    df_pes_ano.plot(kind='bar', ax=axes[1,0], legend=False, color='red')
    df_pes_mes.plot(kind='line', ax=axes[1,1], legend=False, color='green')
    df_teu_ano.plot(kind='bar', ax=axes[2,0], legend=False, color='gray')
    df_teu_mes.plot(kind='line', ax=axes[2,1], legend=False, color='black')

    plt.show()

    #estatistica descritiva
    print('>>> antes')
    print(df[['toperacao', 'tesperaatracacao', 'testadia']].describe())

    #olhando os histogramas e boxplot
    fig, axes = plt.subplots(nrows=3, ncols=2)
    fig.suptitle(titulo + ' - Histogramas e BoxPlot >> antes', fontsize=16)

    df.hist(column='toperacao', ax=axes[0, 0])
    df.boxplot(column='toperacao', ax=axes[0, 1])

    df.hist(column='tesperaatracacao', ax=axes[1, 0])
    df.boxplot(column='tesperaatracacao', ax=axes[1, 1])

    df.hist(column='testadia', ax=axes[2, 0])
    df.boxplot(column='testadia', ax=axes[2, 1])
    plt.show()

    #eliminando outliers e criando 4 classes para trabalho com árvores de decisão - label: toperacao
    df['classe_toperacao'] = 5
    seta_classe(df, 'toperacao', 'classe_toperacao')
    df = df.loc[df['classe_toperacao'] != 5]

    #eliminando outliers e criando 4 classes para trabalho com árvores de decisão - label: tesperaatracacao
    df['classe_tesperaatracacao'] = 5
    seta_classe(df, 'tesperaatracacao', 'classe_tesperaatracacao')
    df = df.loc[df['classe_tesperaatracacao'] != 5]

    #eliminando outliers e criando 4 classes para trabalho com árvores de decisão - label: tesperaatracacao
    df['classe_testadia'] = 5
    seta_classe(df, 'testadia', 'classe_testadia')
    df = df.loc[df['classe_testadia'] != 5]

    print('>>> depois')
    print(df[['toperacao', 'tesperaatracacao', 'testadia']].describe())

    #olhando os histogramas e boxplot
    fig, axes = plt.subplots(nrows=3, ncols=2)
    fig.suptitle(titulo + ' - Histogramas e BoxPlot >> depois', fontsize=16)

    df.hist(column='toperacao', ax=axes[0, 0])
    df.boxplot(column='toperacao', ax=axes[0, 1])

    df.hist(column='tesperaatracacao', ax=axes[1, 0])
    df.boxplot(column='tesperaatracacao', ax=axes[1, 1])

    df.hist(column='testadia', ax=axes[2, 0])
    df.boxplot(column='testadia', ax=axes[2, 1])
    plt.show()

    return df

def classifica_arvore(df, rotulo):
    #arvore de decisão com scikit learn
    classes = ['1', '2', '3', '4']
    atributos = ['cd_berco', 'cd_ano', 'cd_mes','cd_terminal','nacionalidadearmador', 'teu', 'pesocargabruta']

    #df_shuffle = shuffle(df, random_state=1)
    df_shuffle = df.reindex(np.random.permutation(df.index))
    X = df_shuffle[atributos]
    y = df_shuffle[rotulo]                                                                                # classe resultado
    X_treino, X_teste, y_treino, y_teste = train_test_split(X, y, test_size=0.2, random_state=1)                   # 80% para treina e 20% para teste

    #parâmetros básicos
    clf_arvore = DecisionTreeClassifier(criterion='entropy', max_depth=8, random_state=1)                         # entropia como métrica

    #fase de treinamento
    clf_arvore = clf_arvore.fit(X_treino, y_treino)
    y_predicao_treino = clf_arvore.predict(X_treino)
    print("Acuracidade no treino com DT:", accuracy_score(y_treino, y_predicao_treino))
    print("Precisão no treino com DT:", precision_score(y_treino, y_predicao_treino, average='weighted'))

    #matriz de confusão - para treino
    print(confusion_matrix(y_treino, y_predicao_treino))
    print(classification_report(y_treino, y_predicao_treino))

    #fase de testes
    y_predicao_teste = clf_arvore.predict(X_teste)

    #resultado nos testes
    print("Acuracidade no teste com DT:", accuracy_score(y_teste, y_predicao_teste))
    print("Precisão no teste com DT:", precision_score(y_teste, y_predicao_teste, average='weighted'))

    #matriz de confusão - para treino
    print(confusion_matrix(y_teste, y_predicao_teste))
    print(classification_report(y_teste, y_predicao_teste))

    clf_rf = RandomForestClassifier(n_estimators=20, random_state=1)
    clf_rf.fit(X_treino, y_treino)
    y_predicao_treino = clf_rf.predict(X_treino)
    print("Acuracidade no treino com RF:", accuracy_score(y_treino, y_predicao_treino))

    #fase de testes
    y_predicao = clf_rf.predict(X_teste)

    #resultado nos testes
    print("Acuracidade no teste com RF:", accuracy_score(y_teste, y_predicao))

    #visualizando a arvore
    dot_data = export_graphviz(clf_arvore, out_file=None, filled=True, rounded = True, feature_names=atributos, class_names=classes)
    graph = graphviz.Source(dot_data)
    graph.render('arvore', view=True)

#carregando dataset completo - gerado pelas views do sqlite - vw_dataset_cg + vw_dataset_gs + vw_dataset_gl
df_atraca = pd.read_csv('../csv/atraca.csv', low_memory=False)
df_atraca.set_index('idatracacao')

#filtrando Santos / Movimentação de Carga / Longo Curso
df_atraca = df_atraca.loc[df_atraca['cd_portoatracacao'] == 11]      #Santos
df_atraca = df_atraca.loc[df_atraca['cd_tipooperacao'] == 2]         #Movimentação da Carga
df_atraca = df_atraca.loc[df_atraca['cd_tiponavegacaoatracao'] == 3] #Longo Curso

#removendo tempos "inválidos"
df_atraca = df_atraca.loc[df_atraca['toperacao'] > 0]                #Remover tempos zerados
df_atraca = df_atraca.loc[df_atraca['testadia'] > 0]                 #Remover tempos zerados

#separando datasets por tipo de carga devido aos comportamentos diferentes nas atracações
df_cg = df_atraca.loc[df_atraca['cd_tipocarga'] == 1] #carga geral
df_gs = df_atraca.loc[df_atraca['cd_tipocarga'] == 2] #granel sólido
df_gl = df_atraca.loc[df_atraca['cd_tipocarga'] == 3] #granel líquido e gasoso
df_cg_cs = df_cg.loc[df_cg['teu'] == 0]               #somente carga solta
df_cg_cntr = df_cg.loc[df_cg['teu'] > 0]              #somente container

#
#CONTAINERS
#
print('**********************************')
print('*** TRABALHANDO COM CONTAINERS ***')
print('**********************************')

#análise geral
df_cg_cntr = analise_geral(df_cg_cntr, 'toperacao', 'TRABALHANDO COM CONTAINERS')

#classificação com árvores
classifica_arvore(df_cg_cntr, 'classe_toperacao')

#
#CARGA SOLTA
#
print('***********************************')
print('*** TRABALHANDO COM CARGA SOLTA ***')
print('***********************************')

#análise geral
df_cg_cs = analise_geral(df_cg_cs, 'toperacao', 'TRABALHANDO COM CARGA SOLTA')

#classificação com árvores
classifica_arvore(df_cg_cs, 'classe_toperacao')

#
#GRANEL SÓLIDO
#
print('*************************************')
print('*** TRABALHANDO COM GRANEL SÓLIDO ***')
print('*************************************')

#análise geral
df_gs = analise_geral(df_gs, 'toperacao', 'TRABALHANDO COM GRANEL SÓLIDO')

#classificação com árvores
classifica_arvore(df_gs, 'classe_toperacao')

#
#GRANEL LÍQUIDO E GASOSO
#
print('***********************************************')
print('*** TRABALHANDO COM GRANEL LÍQUIDO E GASOSO ***')
print('***********************************************')

#análise geral
df_gl = analise_geral(df_gl, 'toperacao')

#classificação com árvores
classifica_arvore(df_gl, 'classe_toperacao')


# import os

# import numpy as np
# import tensorrt as trt
# import pycuda.driver as cuda  # noqa, must be imported
# import pycuda.autoinit  # noqa, must be imported
# # from sklearn import preprocessing

# from .common import allocate_buffers
# from .common import do_inference

# TRT_LOGGER = trt.Logger()

# class TrtModel(object):
#     def __init__(self, trt_path):
#         self.engine_file = trt_path
#         self.engine = None
#         self.inputs = None
#         self.outputs = None
#         self.bindings = None
#         self.stream = None
#         self.context = None

#     def build(self):
#         with open(self.engine_file, 'rb') as f,
#           trt.Runtime(TRT_LOGGER) as runtime:
#             self.engine = runtime.deserialize_cuda_engine(f.read())
#         self.inputs, self.outputs, self.bindings,
#               self.stream = allocate_buffers(
#             self.engine)
#         self.context = self.engine.create_execution_context()

#     def __call__(self, objects_frame):
#         # lazy load implementation
#         if self.engine is None:
#             self.build()
#         batch_size = objects_frame.shape[0]
#         allocate_place = np.prod(objects_frame.shape)
#         self.inputs[0].host[:allocate_place] =
#           objects_frame.flatten(order='C').astype(np.float32)
#         trt_outputs = do_inference(
#             self.context, bindings=self.bindings,
#             inputs=self.inputs, outputs=self.outputs,
#           stream=self.stream, batch_size=batch_size)
#         embeddings = trt_outputs[0].reshape(-1, 512)
#         embeddings = embeddings[:batch_size]
#         # embeddings = preprocessing.normalize(embeddings)
#         return embeddings

# # TODO: Combine with trt model used for YOLO detector?

import pycuda.driver as cuda

# import pycuda.autoinit
import tensorrt as trt
import numpy as np

EXPLICIT_BATCH = 1 << (int)(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)
TRT_LOGGER = trt.Logger(trt.Logger.WARNING)

def GiB(val):
    """
    ...
    """
    return val * 1 << 30

def ONNX_to_TRT(onnx_model_path=None, trt_engine_path=None, fp16_mode=False):
    """
    仅适用TensorRT V8版本
    生成cudaEngine，并保存引擎文件(仅支持固定输入尺度)

    fp16_mode: True则fp16预测
    onnx_model_path: 将加载的onnx权重路径
    trt_engine_path: trt引擎文件保存路径
    """
    builder = trt.Builder(TRT_LOGGER)
    network = builder.create_network(EXPLICIT_BATCH)
    parser = trt.OnnxParser(network, TRT_LOGGER)

    config = builder.create_builder_config()
    config.max_workspace_size = GiB(1)
    # config.max_batch_size = 1
    if fp16_mode:
        config.set_flag(trt.BuilderFlag.FP16)
    with open(onnx_model_path, "rb") as model:
        assert parser.parse(model.read())
        serialized_engine = builder.build_serialized_network(network, config)

    with open(trt_engine_path, "wb") as f:
        f.write(serialized_engine)  # 序列化

    print("TensorRT file in " + trt_engine_path)
    print("============ONNX->TensorRT SUCCESS============")

class TrtModel:
    """
    TensorRT infer
    """

    def __init__(self, trt_path):
        self.ctx = cuda.Device(0).make_context()
        stream = cuda.Stream()
        TRT_LOGGER = trt.Logger(trt.Logger.INFO)
        runtime = trt.Runtime(TRT_LOGGER)

        # Deserialize the engine from file
        print("Reading trt file:", trt_path)
        with open(trt_path, "rb") as f:
            engine = runtime.deserialize_cuda_engine(f.read())
        context = engine.create_execution_context()

        host_inputs = []
        cuda_inputs = []
        host_outputs = []
        cuda_outputs = []
        bindings = []

        for binding in engine:
            print("bingding:", binding, engine.get_binding_shape(binding))
            size = (
                trt.volume(engine.get_binding_shape(binding))
                * engine.max_batch_size
            )
            dtype = trt.nptype(engine.get_binding_dtype(binding))
            # Allocate host and device buffers
            host_mem = cuda.pagelocked_empty(size, dtype)
            cuda_mem = cuda.mem_alloc(host_mem.nbytes)
            # Append the device buffer to device bindings.
            bindings.append(int(cuda_mem))
            # Append to the appropriate list.
            if engine.binding_is_input(binding):
                self.input_w = engine.get_binding_shape(binding)[-1]
                self.input_h = engine.get_binding_shape(binding)[-2]
                host_inputs.append(host_mem)
                cuda_inputs.append(cuda_mem)
            else:
                host_outputs.append(host_mem)
                cuda_outputs.append(cuda_mem)

        # Store
        self.stream = stream
        self.context = context
        self.engine = engine
        self.host_inputs = host_inputs
        self.cuda_inputs = cuda_inputs
        self.host_outputs = host_outputs
        self.cuda_outputs = cuda_outputs
        self.bindings = bindings
        self.batch_size = engine.max_batch_size

    def __call__(self, img_np_nchw):
        """
        TensorRT推理
        :param img_np_nchw: 输入图像
        """
        self.ctx.push()

        # Restore
        stream = self.stream
        context = self.context
        host_inputs = self.host_inputs
        cuda_inputs = self.cuda_inputs
        host_outputs = self.host_outputs
        cuda_outputs = self.cuda_outputs
        bindings = self.bindings

        np.copyto(host_inputs[0], img_np_nchw.ravel())
        cuda.memcpy_htod_async(cuda_inputs[0], host_inputs[0], stream)
        context.execute_async(
            batch_size=self.batch_size,
            bindings=bindings,
            stream_handle=stream.handle,
        )
        cuda.memcpy_dtoh_async(host_outputs[0], cuda_outputs[0], stream)
        stream.synchronize()
        self.ctx.pop()
        return host_outputs[0]

    def __del__(self):
        self.destroy()

    def destroy(self):
        """
        Remove any context from the top of the context stack,
        deactivating it.
        """
        self.ctx.pop()


from numpy import append
import psycopg2
from ecomere.setting import conn
from flask import request, jsonify
from ecomere.library_ma import CustomersSchema
import json
from psycopg2.extras import DictCursor

customer_schema = CustomersSchema()

def add_customer_service():
    data = request.json
    query = "INSERT INTO customers (customer_name,contact_name,address,city,postalcode,country) VALUES (%s,%s,%s,%s,%s,%s)"
    if ((data and 'customer_name' in data)and('contact_name' in data) and ('address'in data)
    and ('city' in data) and ('postalcode'in data) and ('country' in data)):
        customer_name = data['customer_name']
        contact_name = data['contact_name']
        address = data['address']
        city = data['city']
        postalcode = data['postalcode']
        country = data['country']
        data = (customer_name, contact_name, address, city, postalcode, country)
        print(data)
        try:
            cursor = conn.cursor()
            cursor.execute(query, data)
            conn.commit()
            cursor.close()
            return "Add success"
        except Exception as e:
            print(e)
            conn.rollback()
            return "Can not add Customer"
    else:
        return "Request error"

def get_customer_service_by_id(id):
    try:
        cur = conn.cursor()
        cur.execute(f"SELECT * FROM customers WHERE customerid = {id}")
        rows = cur.fetchall()
        #print(rows[0])
        for row in rows:
            data = {
                "Customer name": row[1],
                "Contact name": row[2],
                "Address": row[3],
                "City": row[4],
                "Postal Code": row[5],
                "Country": row[6]
            }
        #print(data)
        if rows:
            return data
        else:
            return "Not found customer"
    except IndentationError:
        print(IndentationError)
        return "Request error"

def get__all_customer_service():
    try:
        data = []
        #cur = conn.cursor()
        #cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
        cur = conn.cursor(cursor_factory=DictCursor)
        cur.execute("SELECT * FROM customers")
        rows = cur.fetchall()
        #print(rows[0])
        # keys =  ["Customer Id", "Customer name", "Contact name", "Address", "City", "Postal Code", "Country"]
        # data = [{k: v for k, v in zip(keys, tup)} for tup in rows]
        # data_json =json.dumps(data, indent=6)
        for row in rows:
            data.append(dict(row))
        #data = json.dumps(data, indent=6)
        cur.close()
        #print(data_json)
        if rows:
            return jsonify(data)
        else:
            return "Not found customer"

    except IndentationError:
        print(IndentationError)
        return "Request error"

def update_address_customer_by_id_service(id):
    data = request.json
    #print(data["address"])
    query = "UPDATE customers SET address = %s WHERE customerid = %s "
    updated_rows = 0
    try:
        cur = conn.cursor()
        cur.execute(query, (data["address"], id))
        updated_rows = cur.rowcount
        print(updated_rows)
        conn.commit()
        cur.close()
        return  f"Updated address to Customer-{id} successfully "
    except (Exception, psycopg2.DatabaseError) as error:
        print(error)
        return "Can not updated address customer"
    finally:
        if conn is not None:
            conn.close()

def  delete_customer_by_id_service(id):
    try:
        cur = conn.cursor()
        cur.execute(f"DELETE FROM customers WHERE customerid = {id}")
        conn.commit()
        conn.close()
        return "Delete customer success",200
    except Exception as e:
        return f"Delete fail, {e}"


def retry(exc=Exception, tries=3):
    def wrapper(f):
        def wrapped(*args, **kwargs):
            _tries = tries
            while True:
                try:
                    return f(*args, **kwargs)
                except exc:
                    _tries -= 1
                    if _tries <= 0:
                        raise
        return wrapped
    return wrapper

def retry_call(f, exc=Exception, args=None, kwargs=None, tries=3):
    _tries = tries
    args = args or []
    kwargs = kwargs or {}
    while True:
        try:
            return f(*args, **kwargs)
        except exc:
            _tries -= 1
            if _tries <= 0:
                raise


def favorite_book(title):
    print(f"Moja ulubiona książka ma tytuł {title}.")

favorite_book("Książka")

def describe_pet(animal_name, animal_type="pies"):
    """Wyswietla informcje o zwierzęciu"""
    print(f"\n Moje zwierzę to {animal_type}")
    print(f"Mój {animal_type} ma na imię {animal_name.title()}")

describe_pet("harry")

# describe_pet(animal_name="harry", animal_type="chomik")

def make_shirt(size="XXL", text="Uwielbiam Pythona"):
    print(f"Moja koszulka ma rozmiar {size} i ma napis: {text}")

make_shirt()
make_shirt(size="L")

def get_forrmated_name(first_name, last_name, middle_name=""):
    """Zwraca elegancko sformatowane pełne imie i nazwisko"""
    if middle_name:
        full_name = f"{first_name} {last_name} {middle_name}"
    else:
        full_name = f"{first_name} {last_name}"
    return full_name.title()

musician = get_forrmated_name("jimi", "hendrix")
print(musician)
musician = get_forrmated_name("john", "lee", 'hooker')
print(musician)

def build_person(first_name, last_name, age=None):
    """Zwraca słownik informacji"""
    person = {'first': first_name, 'last': last_name}
    if age:
        person['age'] = age
    return person

musician = build_person('jimi', 'hendrix', age=27)
print(musician)

def make_album(name, title_alboom, liczba=None):
    plyta = {'nazwa': name, 'tytul': title_alboom}
    if liczba:
        plyta['liczba'] = liczba
    return plyta

while True:
    print('Podaj artystę: ')
    print('Jeśli chcesz zakończyć napisz q')
    artysta = input('Artysta')
    if artysta == 'q':
        break
    print("podaj tytuł płyty")
    print('Jeśli chcesz zakończyć napisz q')
    tytul = input("Podaj tytuł")
    if tytul == 'q':
        break

    cala_plyta = make_album(artysta, tytul)
    print(cala_plyta)

# ulubiona_plyta = make_album('republika', 'republika', liczba=11)
# print(ulubiona_plyta)

# def get_forrmated_name(first_name, last_name):
#     """Zwraca elegancko sformatowane pełne imie i nazwisko"""
#     full_name = f"{first_name} {last_name}"
#     return full_name
#
#
# while True:
#     print("Prosze podac imie i nazwisko: ")
#     print("Jeśli chcesz zakończyć wciśnij q")
#     f_name = input("Imie: ")
#     if f_name == "q":
#         break
#     l_name = input("Nawisko: ")
#     if l_name == "q":
#         break
#
#     formatted_name = get_forrmated_name(f_name, l_name)
#     print(formatted_name.title())


import pandas

url = "https://finance.naver.com/"

table = pandas.read_html(url,encoding="cp949")
# print(type(table))
# print(len(table))
# print(table[1]) #인덱스로 상항가를 추출 한다.

top = table[0]
print(type(top))# dataframe 타입은 인덱스


import unittest
import allure
from config.setup import get_driver
from data.mobile_params import return_policy_text, shipping_taxes_text, test_report
from utils.mobile.locator_info import schedule_title, share_frame, confirm_button, \
    return_policy, Shipping_taxes, previous_question, next_question, thanks
from utils.mobile.user_actions import Actions

@allure.severity(allure.severity_level.CRITICAL)
@allure.feature("Live")
class TestLiveButtons(unittest.TestCase):

    def setUp(self) -> None:
        self.driver = get_driver(no_rest=True)
        global do
        do = Actions(self.driver)

    def tearDown(self):
        self.driver.quit()

    @allure.story("shop")
    def test1_tap_shop(self) -> None:
        do.tap_shop()
        do.assert_element_by_xpath(return_policy, 'Open shop page success')
        do.assert_element_by_xpath_attr(return_policy, 'label', return_policy_text, 'policy text correct')
        do.assert_element_by_xpath_attr(Shipping_taxes, 'label', shipping_taxes_text, 'Shipping&taxes text correct')
        do.tap_follow_shop_page()
        do.swap_down_shop_page()
        do.tap_shop()
        do.tap_unfollow_shop_page()
        do.tap_report_shop_page()
        do.assert_element(confirm_button, 'Open report page success', 10)
        do.tap_back()
        do.swap_down_shop_page()

    @allure.story("Flag")
    def test2_tap_flag(self) -> None:
        do.tap_flag()
        do.assert_element(confirm_button, 'Open report page success', 10)
        do.assert_element_by_attr(previous_question, 'enabled', 'false', "This is first page")
        do.input_email_answer(test_report['email'])
        do.tap_ok()
        do.input_name_answer(test_report['user'])
        do.tap_ok()
        do.select_an_option()
        do.input_addition(test_report['add'])
        do.tap_ok()
        do.select_screenshot()
        do.assert_element_by_attr(next_question, 'enabled', 'false', "This is last page")
        is_last_page = True
        is_first_page = False
        while is_last_page is True:
            do.tap_pre_question()
            if do.get_attr(previous_question,'enabled') == 'false':
                is_first_page = True
                is_last_page = False
        while is_first_page is True:
            do.tap_next_question()
            if do.get_attr(next_question,'enabled') == 'false':
                break
        do.tap_submit_report()
        do.assert_element(thanks, 'Submit success')
        do.swap_down_report()

    @allure.story("share")
    def test3_tap_share(self) -> None:
        do.tap_share()
        do.assert_element(share_frame, 'Open share success')
        do.tap_close_share()

    @allure.story("schedule")    # listing sold out
    def test4_tap_schedule(self) -> None:
        do.tap_schedule()
        do.assert_element(schedule_title, 'Open schedule success')
        do.swap_down_schedule()


from django.shortcuts import render

# Create your views here.
def root (request):

    return render(request,'index.html' )

def show(request):

    name =request.POST['userName']
    location = request.POST['dojoLocations']
    language = request.POST['FavoritetLanguage']
    comment= request.POST['comment']
    Gender=request.POST['Gender']
    vehicle=request.POST['vehicle1']
    context ={
            'show_name' : name,
            'show_Location' : location,
            'show_language' : language,
            'show_comment' : comment,
            'show_Gender': Gender ,
            'show_vehicle': vehicle
        }
    return render(request, 'show.html',context)


import base64

import cv2
import numpy as np

def get_lr(optimizer, n):
    return optimizer.param_groups[n]['lr']

def get_momentum(optimizer, mom_name):
    for param_group in optimizer.param_groups:
        if mom_name == 'momentum':
            return param_group[mom_name]
        elif mom_name == 'betas':
            return param_group[mom_name][0]

def np_to_base64_utf8_str(arr):
    np_buff = arr.tobytes()
    np_buff_b64_bytes = base64.b64encode(np_buff)
    np_buff_base64_utf8_string = np_buff_b64_bytes.decode('utf-8')
    return np_buff_base64_utf8_string

def rand_bbox(size, lam):
    W = size[2]
    H = size[3]
    cut_rat = np.sqrt(1. - lam)
    cut_w = np.int(W * cut_rat)
    cut_h = np.int(H * cut_rat)

    # uniform
    cx = np.random.randint(W)
    cy = np.random.randint(H)

    bbx1 = np.clip(cx - cut_w // 2, 0, W)
    bby1 = np.clip(cy - cut_h // 2, 0, H)
    bbx2 = np.clip(cx + cut_w // 2, 0, W)
    bby2 = np.clip(cy + cut_h // 2, 0, H)

    return bbx1, bby1, bbx2, bby2

def set_lr(optimizer, lrs):
    for param_group, lr in zip(optimizer.param_groups, lrs):
        param_group['lr'] = lr

def set_momentum(optimizer, mom_name, momentum):
    for param_group in optimizer.param_groups:
        if mom_name == 'momentum':
            param_group[mom_name] = momentum
        elif mom_name == 'betas':
            param_group[mom_name] = (momentum, 0.999)


import random
import time

from datetime import datetime
from django.conf import settings
from django.db import models
from django.db.models import Q
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist

HOURS_GROWTH_CONSTANT = 1.043
HOURS_MULTIPLIER = 2.0
HOURS_OFFSET = 1.9
TIME_UNIT_MULTIPLIER = 0.4
TIME_UNIT_OFFSET = 0.0
XP_MULTIPLIER = 10.0

def ellipsis(width):
  def _decorator(function):
    def _wrapper(*args, **kwargs):
      text = function(*args, **kwargs)
      if len(text) > width:
        return text[:width - 3] + '...'
      else:
        return text
    return _wrapper
  return _decorator

def randSecret():
  adverbs = [
      'absurdly', 'catastrophically', 'characteristically', 'closely', 'doubtfully', 'dutifully',
      'eerily', 'energetically', 'fantastically', 'firmly', 'fully', 'furtively', 'indubitably',
      'inexplicably', 'inoperably', 'naively', 'paradoxically', 'partially', 'rambunctiously',
      'regretfully', 'romantically', 'simply', 'sporadically', 'stinkily', 'surgically',
      'suspiciously', 'truthfully', 'unquestionably', 'wonderously'
  ]
  adjectives = [
      'bamboozled', 'bemused', 'bifurcated', 'blushing', 'cantankerous', 'cheeky', 'courageous',
      'cuddly', 'fungible', 'gobsmacked', 'greasy', 'groggy', 'grotesque', 'gunky', 'janky',
      'lackadaisical', 'loopy', 'muddy', 'namby-pamby', 'persnickety', 'prickly', 'rapscallion',
      'smelly', 'snarky', 'suspicious', 'wild', 'wonky', 'zealous'
  ]
  nouns = [
      'bazinga', 'bootlegger', 'buccaneer', 'bumfuzzle', 'canoodle', 'carbuncle', 'caterwaul',
      'cattywampus', 'conniption', 'didgeridoo', 'doodle', 'doohickey', 'fiddledeedee', 'girdle',
      'gumbo', 'hornswoggle', 'hullabaloo', 'kahuna', 'katydid', 'kerplunk', 'kinkajou', 'monkey',
      'mugwump', 'noggin', 'pantaloon', 'prestidigitation', 'pickle', 'proctor', 'rumpus',
      'scootch', 'scuttlebutt', 'shebang', 'snuffle', 'spelunker', 'spork', 'sprocket', 'squeegee',
      'tater', 'tuber', 'viper', 'waddle', 'walkabout', 'wasabi', 'weasel', 'whatnot', 'wombat',
      'zeitgeist'
  ]
  adverb = adverbs[random.randint(0, len(adverbs) - 1)]
  adjective = adjectives[random.randint(0, len(adjectives) - 1)]
  noun = nouns[random.randint(0, len(nouns) - 1)]
  article = 'an' if adverb[0] in 'aeiou' else 'a'
  return '%s %s %s %s' % (article, adverb, adjective, noun)

class Track(models.Model):
  name = models.CharField(max_length=64, unique=True, db_index=True)
  description = models.TextField()
  mission = models.CharField(max_length=128)

  @ellipsis(100)
  def __unicode__(self):
    return '%s: %s' % (self.name, self.description)

  class Meta:
    ordering = ['name']

class Level(models.Model):
  name = models.CharField(max_length=64)
  description = models.TextField()
  rank = models.PositiveSmallIntegerField()
  track = models.ForeignKey(Track, related_name='levels')
  is_public = models.BooleanField(default=True)

  def __unicode__(self):
    return '(%s) %d: %s' % (self.track.name, self.rank, self.name)

  @staticmethod
  def hours_needed_in(rank):
    if rank > 0:
      # Round to two decimals for simplicity's sake.
      return round(HOURS_MULTIPLIER * rank ** HOURS_GROWTH_CONSTANT - HOURS_OFFSET, 2)
    else:
      return 0.0

  @staticmethod
  def xp_per_hours_work_in(rank):
    if rank > 0:
      return int(round(XP_MULTIPLIER * rank ** HOURS_GROWTH_CONSTANT))
    else:
      return 0

  @staticmethod
  def cumulative_xp_needed_for(rank):
    xp_needed = 0
    for rank_i in xrange(rank + 1):
      xp_needed += round(Level.hours_needed_in(rank_i) * Level.xp_per_hours_work_in(rank_i))
    return xp_needed

  def top_10_user_tracks(self):
    return self.user_tracks.order_by('-xp')[:10]

  def user_count(self):
    return self.user_tracks.count()

  def next(self):
    try:
      return self.track.levels.get(rank=self.rank + 1)
    except ObjectDoesNotExist:
      return None

  class Meta:
    ordering = ['track', 'rank']
    unique_together = (('rank', 'track'), ('name', 'track'))

class Badge(models.Model):
  name = models.CharField(max_length=64)
  level = models.ForeignKey(Level, related_name='badges')
  order = models.FloatField()
  description = models.CharField(max_length=128)
  training = models.TextField()
  challenge = models.CharField(max_length=256)
  BRONZE, SILVER, GOLD, DIAMOND = 1, 2, 4, 6
  GRADES = {BRONZE: 'Bronze',
            SILVER: 'Silver',
            GOLD: 'Gold',
            DIAMOND: 'Diamond'}
  grade = models.SmallIntegerField(choices=GRADES.items(), default=BRONZE)
  is_required = models.BooleanField(default=False)
  requires_verification = models.BooleanField(default=False)

  @ellipsis(100)
  def __unicode__(self):
    return '(%s/%s) %s: %s' % (self.grade, self.level.track.name, self.name,
                               self.description)

  def hours_needed(self):
    if self.level.rank > 0:
      return round(self.grade *
                   (TIME_UNIT_MULTIPLIER * self.level.rank - TIME_UNIT_OFFSET),
                   2)
    else:
      return 0.0

  def xp(self):
    return int(round(self.hours_needed() * Level.xp_per_hours_work_in(self.level.rank)))

  def user_count(self):
    return self.user_tracks.count()

  def track_name(self):
    return self.level.track.name

  class Meta:
    ordering = ['level__track', 'level__rank', 'order']

class Verification(models.Model):
  user = models.ForeignKey(User, related_name='verifications')
  badge = models.ForeignKey(Badge, related_name='verifications')
  verifier = models.ForeignKey(User, related_name='verifications_verified', blank=True, null=True)
  text = models.TextField(blank=True)
  youtube_id = models.SlugField(max_length=11, blank=True)
  UNSUBMITTED, UNVERIFIED, VERIFIED = 'X', 'U', 'V'
  STATUSES = {UNSUBMITTED: 'Unsubmitted',
              UNVERIFIED: 'Unverified',
              VERIFIED: 'Verified'}
  status = models.CharField(max_length=1, choices=STATUSES.items(), default=UNSUBMITTED)
  timestamp = models.DateTimeField(default=datetime.now, editable=False, blank=True)

  def __unicode__(self):
    return '%s for %s - %s' % (self.badge.name, self.user.username, self.status)

  def to_dict(self):
    return {
        'pk': self.pk,
        'user': self.user.username,
        'badge': self.badge.name,
    }

  class Meta:
    get_latest_by = 'timestamp'
    ordering = ['status', 'badge', 'user']
    unique_together = ('user', 'badge')

class UserProfile(models.Model):
  user = models.OneToOneField(User, primary_key=True, related_name='profile')
  MALE, FEMALE, OTHER = 'M', 'F', 'O'
  GENDERS = {MALE: 'Male',
             FEMALE: 'Female',
             OTHER: 'Other'}
  gender = models.CharField(max_length='1', choices=GENDERS.items())

  def xp(self):
    return sum(user_track.xp for user_track in self.user.user_tracks.all())

  def __unicode__(self):
    return '%s profile' % (self.user.username,)

class UserTrack(models.Model):
  user = models.ForeignKey(User, related_name='user_tracks')
  track = models.ForeignKey(Track, related_name='user_tracks')
  level = models.ForeignKey('Level', related_name='user_tracks')
  badges = models.ManyToManyField('Badge', blank=True, related_name='user_tracks')
  xp = models.PositiveIntegerField(default=0)

  def __unicode__(self):
    return '%s/%s' % (self.user, self.track.name)

  def current_challenges(self):
    return (
        self.user.verifications
        .filter(status__in=(Verification.UNSUBMITTED, Verification.UNVERIFIED),
                badge__level__track=self.track)
        .order_by('-timestamp'))

  def next_challenges(self):
    return (
        Badge.objects
        .filter(level=self.level.next())
        .exclude(verifications__user=self.user,
                 verifications__status__in=(Verification.UNSUBMITTED,
                                            Verification.UNVERIFIED,
                                            Verification.VERIFIED))
        .order_by('order'))

  def challenges_to_verify(self):
    return (
        Verification.objects
        .exclude(user=self.user)
        .filter(Q(badge__in=self.badges.all()) |
                Q(badge__level__track=self.track,
                  badge__level__rank__lt=self.level.rank),
                status=Verification.UNVERIFIED)
        .order_by('?'))

  def award_badge(self, verification, verifier):
    # Close the verification.
    verification.status = Verification.VERIFIED
    verification.verifier = verifier
    verification.save()

    # Award the badge and xp.
    self.badges.add(verification.badge)
    self.xp += verification.badge.xp()

    # Award the next level, if available.
    changed_levels = False
    if self.next_challenges().filter(is_required=True).count() == 0:
      next_level = self.level.next()
      if next_level:
        self.level = next_level
        changed_levels = True

    self.save()

    # Send notifications from Prometheus.
    WallPost(user=self.user,
             poster=User.PROMETHEUS,
             text="Congratulations! You've earned the badge \"%s\" in %s." %
                  (verification.badge.name, self.track.name),
             is_public=False,
             verification=verification).save()
    if changed_levels:
      WallPost(user=self.user,
               poster=User.PROMETHEUS,
               text="Congratulations! You've achieved level %d in %s and earned the title \"%s\"." %
                    (self.level.rank, self.track.name, self.level.name),
               is_public=False,
               verification=verification).save()

    return changed_levels

  class Meta:
    ordering = ['user', 'track']
    unique_together = ('user', 'track')

class WallPost(models.Model):
  user = models.ForeignKey(User, related_name='wall_posts')
  poster = models.ForeignKey(User, related_name='wall_posts_posted')
  MAX_TEXT_LENGTH = 512
  text = models.CharField(max_length=MAX_TEXT_LENGTH)
  is_public = models.BooleanField(default=True)
  verification = models.ForeignKey(Verification, related_name='wall_posts', blank=True, null=True)
  timestamp = models.DateTimeField(default=datetime.now, editable=False, blank=True)

  @ellipsis(100)
  def __unicode__(self):
    return u'@%s: %s \u2014 %s on %s' % (self.user.username, self.text, self.poster.username,
                                         datetime.date(self.timestamp).strftime('%b %d, \'%y'))

  def to_dict(self):
    ret = {
        'pk': self.pk,
        'user': self.user.username,
        'poster': self.poster.username,
        'text': self.text,
        'is_public': self.is_public,
        'timestamp': int(time.mktime(self.timestamp.timetuple())),
    }
    if self.verification:
      ret['verification'] = self.verification.to_dict()
    return ret

  class Meta:
    get_latest_by = 'timestamp'
    ordering = ['user', '-timestamp']

class Invitation(models.Model):
  email = models.EmailField()
  secret = models.CharField(max_length=75, default=randSecret)
  created = models.DateTimeField(default=datetime.now, editable=False, blank=True)
  emails_sent = models.PositiveSmallIntegerField(default=0)
  last_email_timestamp = models.DateTimeField(blank=True, null=True)
  claimer = models.OneToOneField(User, related_name='invitation', blank=True, null=True)

  def __unicode__(self):
    return '%s: %s - %s' % (self.email, self.secret,
                            datetime.date(self.created).strftime('%b %d, \'%y'))

  class Meta:
    get_latest_by = 'created'
    ordering = ['created']

def user_can_verify(self, verification):
  if not self.is_authenticated():
    return False
  elif self == verification.user:
    return not verification.badge.requires_verification
  elif verification.status != Verification.UNVERIFIED:
    return False
  else:
    try:
      verification_badge = verification.badge
      verification_level = verification_badge.level
      user_track = self.user_tracks.get(track=verification_level.track)
      if user_track.level.rank > verification_level.rank:
        return True
      else:
        return user_track.badges.filter(pk=verification_badge.pk).exists()
    except ObjectDoesNotExist:
      return False

User.add_to_class('can_verify', user_can_verify)

# Monkey-patch the Prometheus User onto the User object for convenience.
User.PROMETHEUS = User.objects.get(pk=7)


import sys
from PySide2 import QtCore, QtWidgets

class DialogWindow(QtWidgets.QDialog):  # QtWidgets.QDialog를 상속받음.
 def __init__(self):
  QtWidgets.QDialog.__init__(self)
  self.setWindowTitle("Dialog Window")  # 대화 상자 맨 위의 window title을 Dialog Window로 설정.
  vbox = QtWidgets.QVBoxLayout(self)  # vertical 1개
  hbox1 = QtWidgets.QHBoxLayout()
  hbox2 = QtWidgets.QHBoxLayout()   # horizontal 2개
  self.ok = QtWidgets.QPushButton("OK", self)   # OK push button
  self.cancel = QtWidgets.QPushButton("Cancel", self)   # Cancel push button

  vbox.addLayout(hbox1)
  vbox.addLayout(hbox2)   # vertical 2개.

  hbox1.addWidget(QtWidgets.QLabel("Enter your name", self))    # addWidget으로 1번째 horizontal 줄에 Qlabel 넣음.
  self.lineedit = QtWidgets.QLineEdit(self)
  hbox1.addWidget(self.lineedit)    # QLineEdit 넣음.
  hbox2.addWidget(self.ok)    # 2번째 horizontal 줄에 self.ok 에 저장돼있던 OK push button 넣음.
  hbox2.addWidget(self.cancel)

  self.ok.clicked.connect(self.accept)    # OK button 클릭 시, accept
  self.cancel.clicked.connect(self.reject)

if __name__ == "__main__":
 app = QtWidgets.QApplication(sys.argv)
 dg = DialogWindow()
 result = dg.exec_()
 if result == QtWidgets.QDialog.Accepted:
  print("Your name is", dg.lineedit.text())
 elif result == QtWidgets.QDialog.Rejected:
  print("Input canceled")


#__package__ = 'basics.second.third'

from .utils import multi

def calc(a, b):
    multi("==", 10)
    print(f"a + b = {a + b}")

if __name__ == '__main__':
    calc(2, 3)
    print("In module products __package__, __name__ ==", __package__, __name__)


import sys
if sys.platform == 'darwin':
    """Inputhook for OS X

    Calls NSApp / CoreFoundation APIs via ctypes.
    """

    # obj-c boilerplate from appnope, used under BSD 2-clause

    import ctypes
    import ctypes.util
    from threading import Event

    objc = ctypes.cdll.LoadLibrary(ctypes.util.find_library('objc'))

    void_p = ctypes.c_void_p

    objc.objc_getClass.restype = void_p
    objc.sel_registerName.restype = void_p
    objc.objc_msgSend.restype = void_p
    objc.objc_msgSend.argtypes = [void_p, void_p]

    msg = objc.objc_msgSend

    def _utf8(s):
        """ensure utf8 bytes"""
        if not isinstance(s, bytes):
            s = s.encode('utf8')
        return s

    def n(name):
        """create a selector name (for ObjC methods)"""
        return objc.sel_registerName(_utf8(name))

    def C(classname):
        """get an ObjC Class by name"""
        return objc.objc_getClass(_utf8(classname))

    # end obj-c boilerplate from appnope

    # CoreFoundation C-API calls we will use:
    CoreFoundation = ctypes.cdll.LoadLibrary(ctypes.util.find_library('CoreFoundation'))

    CFFileDescriptorCreate = CoreFoundation.CFFileDescriptorCreate
    CFFileDescriptorCreate.restype = void_p
    CFFileDescriptorCreate.argtypes = [void_p, ctypes.c_int, ctypes.c_bool, void_p]

    CFFileDescriptorGetNativeDescriptor = CoreFoundation.CFFileDescriptorGetNativeDescriptor
    CFFileDescriptorGetNativeDescriptor.restype = ctypes.c_int
    CFFileDescriptorGetNativeDescriptor.argtypes = [void_p]

    CFFileDescriptorEnableCallBacks = CoreFoundation.CFFileDescriptorEnableCallBacks
    CFFileDescriptorEnableCallBacks.restype = None
    CFFileDescriptorEnableCallBacks.argtypes = [void_p, ctypes.c_ulong]

    CFFileDescriptorCreateRunLoopSource = CoreFoundation.CFFileDescriptorCreateRunLoopSource
    CFFileDescriptorCreateRunLoopSource.restype = void_p
    CFFileDescriptorCreateRunLoopSource.argtypes = [void_p, void_p, void_p]

    CFRunLoopGetCurrent = CoreFoundation.CFRunLoopGetCurrent
    CFRunLoopGetCurrent.restype = void_p

    CFRunLoopAddSource = CoreFoundation.CFRunLoopAddSource
    CFRunLoopAddSource.restype = None
    CFRunLoopAddSource.argtypes = [void_p, void_p, void_p]

    CFRelease = CoreFoundation.CFRelease
    CFRelease.restype = None
    CFRelease.argtypes = [void_p]

    CFFileDescriptorInvalidate = CoreFoundation.CFFileDescriptorInvalidate
    CFFileDescriptorInvalidate.restype = None
    CFFileDescriptorInvalidate.argtypes = [void_p]

    # From CFFileDescriptor.h
    kCFFileDescriptorReadCallBack = 1
    kCFRunLoopCommonModes = void_p.in_dll(CoreFoundation, 'kCFRunLoopCommonModes')

    def _NSApp():
        """Return the global NSApplication instance (NSApp)"""
        return msg(C('NSApplication'), n('sharedApplication'))

    def _wake(NSApp):
        """Wake the Application"""
        event = msg(C('NSEvent'),
            n('otherEventWithType:location:modifierFlags:'
              'timestamp:windowNumber:context:subtype:data1:data2:'),
            15, # Type
            0, # location
            0, # flags
            0, # timestamp
            0, # window
            None, # context
            0, # subtype
            0, # data1
            0, # data2
        )
        msg(NSApp, n('postEvent:atStart:'), void_p(event), True)

    _triggered = Event()

    def _input_callback(fdref, flags, info):
        """Callback to fire when there's input to be read"""
        _triggered.set()
        CFFileDescriptorInvalidate(fdref)
        CFRelease(fdref)
        NSApp = _NSApp()
        msg(NSApp, n('stop:'), NSApp)
        _wake(NSApp)

    _c_callback_func_type = ctypes.CFUNCTYPE(None, void_p, void_p, void_p)
    _c_input_callback = _c_callback_func_type(_input_callback)

    def _stop_on_read(fd):
        """Register callback to stop eventloop when there's data on fd"""
        _triggered.clear()
        fdref = CFFileDescriptorCreate(None, fd, False, _c_input_callback, None)
        CFFileDescriptorEnableCallBacks(fdref, kCFFileDescriptorReadCallBack)
        source = CFFileDescriptorCreateRunLoopSource(None, fdref, 0)
        loop = CFRunLoopGetCurrent()
        CFRunLoopAddSource(loop, source, kCFRunLoopCommonModes)
        CFRelease(source)

    def inputhook(context):
        """Inputhook for Cocoa (NSApp)"""
        NSApp = _NSApp()
        # Modified against IPython master (see
        # https://github.com/ipython/ipython/pull/10150#issuecomment-277897126).
        window_count = msg(
            msg(NSApp, n('windows')),
            n('count')
        )
        if not window_count:
            return
        _stop_on_read(context.fileno())
        msg(NSApp, n('run'))
        if not _triggered.is_set():
            # app closed without firing callback,
            # probably due to last window being closed.
            # Run the loop manually in this case,
            # since there may be events still to process (#9734)
            CoreFoundation.CFRunLoopRun()