#-------------------------------------------------------------------------------
# Name:        CMU Tool 1.0
# Purpose:
# Author:      Molly Moore
# Created:     10/13/2021
#-------------------------------------------------------------------------------

######################################################################################################################################################
## Import packages and define environment settings
######################################################################################################################################################

import arcpy,os,sys,string
from getpass import getuser
import sqlite3 as lite
import pandas as pd

arcpy.env.overwriteOutput = True
arcpy.env.transferDomains = True

######################################################################################################################################################
## Define universal variables and functions
######################################################################################################################################################

def element_type(elcode):
    """Takes ELCODE as input and returns CMU element type code."""
    if elcode.startswith('AAAA'):
        et = 'AAAA'
    elif elcode.startswith('AAAB'):
        et = 'AAAB'
    elif elcode.startswith('AB'):
        et = 'AB'
    elif elcode.startswith('AF'):
        et = 'AF'
    elif elcode.startswith('AM'):
        et = 'AM'
    elif elcode.startswith('AR'):
        et = 'AR'
    elif elcode.startswith('C') or elcode.startswith('H'):
        et = 'CGH'
    elif elcode.startswith('ICMAL'):
        et = 'ICMAL'
    elif elcode.startswith('ILARA'):
        et = 'ILARA'
    elif elcode.startswith('IZSPN'):
        et = 'IZSPN'
    elif elcode.startswith('IICOL02'):
        et = 'IICOL02'
    elif elcode.startswith('IICOL'):
        et = 'IICOL'
    elif elcode.startswith('IIEPH'):
        et = 'IIEPH'
    elif elcode.startswith('IIHYM'):
        et = 'IIHYM'
    elif elcode.startswith('IILEP'):
        et = 'IILEP'
    elif elcode.startswith('IILEY') or elcode.startswith('IILEW') or elcode.startswith('IILEV') or elcode.startswith('IILEU'):
        et = 'IILEY'
    elif elcode.startswith('IIODO'):
        et = 'IIODO'
    elif elcode.startswith('IIORT'):
        et = 'IIORT'
    elif elcode.startswith('IIPLE'):
        et = 'IIPLE'
    elif elcode.startswith('IITRI'):
        et = 'IITRI'
    elif elcode.startswith('IMBIV'):
        et = 'IMBIV'
    elif elcode.startswith('IMGAS'):
        et = 'IMGAS'
    elif elcode.startswith('I'):
        et = 'I'
    elif elcode.startswith('N'):
        et = 'N'
    elif elcode.startswith('P'):
        et = 'P'
    else:
        arcpy.AddMessage("Could not determine element type")
        et = None
    return et

######################################################################################################################################################
## Begin toolbox
######################################################################################################################################################

class Toolbox(object):
    def __init__(self):
        """Define the toolbox (the name of the toolbox is the name of the .pyt file)."""
        self.label = "CMU Tools v1"
        self.alias = "CMU Tools v1"
        self.canRunInBackground = False
        self.tools = [CreateCMU,FillAttributes]

######################################################################################################################################################
## Begin create CMU tool - this tool creates the core and supporting CMUs and fills their initial attributes
######################################################################################################################################################

class CreateCMU(object):
    def __init__(self):
        self.label = "1 Create CMU"
        self.description = ""
        self.canRunInBackground = False

    def getParameterInfo(self):
        site_name = arcpy.Parameter(
            displayName = "Site Name",
            name = "site_name",
            datatype = "GPString",
            parameterType = "Required",
            direction = "Input")

        site_desc = arcpy.Parameter(
            displayName = "Site Description",
            name = "site_desc",
            datatype = "GPString",
            parameterType = "Optional",
            direction = "Input")

        cpp_core = arcpy.Parameter(
            displayName = "Selected CPP Core(s)",
            name = "cpp_core",
            datatype = "GPFeatureLayer",
            parameterType = "Required",
            direction = "Input")
        cpp_core.value = r'CPP\CPP Core'

        params = [site_name,site_desc,cpp_core]
        return params

    def isLicensed(self):
        return True

    def updateParameters(self, params):
        return

    def updateMessages(self, params):
        return

    def execute(self, params, messages):

        site_name = params[0].valueAsText
        site_desc = params[1].valueAsText
        cpp_core = params[2].valueAsText

        mem_workspace = "memory"

        cmu = r"PGLMT_v2\\CMU"
        spec_tbl = r"PNHP.DBO.CMU_SpeciesTable"

        eo_reps = r'W:\\Heritage\\Heritage_Data\\Biotics_datasets.gdb\\eo_reps'

######################################################################################################################################################
## create CMU shape and get CMU attributes
######################################################################################################################################################

        desc = arcpy.Describe(cpp_core)
        if not desc.FIDSet == '':
            pass
        else:
            arcpy.AddWarning("No CPP Cores are selected. Please make a selection and try again.")
            sys.exit()

        desc = arcpy.Describe(cmu)
        if not desc.FIDSet == '':
            arcpy.AddWarning("There is currently a selection on the CMU layer. Please clear the selection and try again.")
            sys.exit()
        else:
            pass

        arcpy.AddMessage("......")
        # create list of eo ids for all selected CPPs that are current or approved
        with arcpy.da.SearchCursor(cpp_core,["EO_ID","Status"]) as cursor:
            eoids = sorted({row[0] for row in cursor if row[1] != "n"})
        # create list of eo ids for all selected CPPs that are not approved
        with arcpy.da.SearchCursor(cpp_core,["EO_ID","Status"]) as cursor:
            excluded_eoids = sorted({row[0]for row in cursor if row[1] == "n"})

        # add reporting messages about which CPPs are being excluded
        if excluded_eoids:
            arcpy.AddWarning("Selected CPPs with the following EO IDs are being excluded because they were marked as not approved: "+ ','.join([str(x) for x in excluded_eoids]))
        else:
            pass

        # add reporting messages about which CPPs are being included and exit with message if no selected CPPs are current or approved.
        if len(eoids) != 0:
            arcpy.AddMessage("Selected CPPs with the following EO IDs are being used to create this CMU: "+','.join([str(x) for x in eoids]))
            arcpy.AddMessage("......")
        else:
            arcpy.AddWarning("Your CPP selection does not include any current or approved CPPs and we cannot proceed. Goodbye.")
            sys.exit()

        # create sql query based on number of CPPs included in query.
        if len(eoids) > 1:
            sql_query = '"EO_ID" in {}'.format(tuple(eoids))
        else:
            sql_query = '"EO_ID" = {}'.format(eoids[0])

        arcpy.AddMessage("Creating and attributing CMU core for site: "+ site_name)
        arcpy.AddMessage("......")
        # create cpp_core layer from selected CPPs marked as current or approved and dissolve to create temporary CMU geometry
        cpp_core_lyr = arcpy.MakeFeatureLayer_management(cpp_core, "cpp_core_lyr", sql_query)
        temp_cmu = os.path.join(mem_workspace,"temp_cmu")
        temp_cmu = arcpy.Dissolve_management(cpp_core_lyr, temp_cmu)

        # get geometry token from cmu
        with arcpy.da.SearchCursor(temp_cmu,"SHAPE@") as cursor:
            for row in cursor:
                geom = row[0]

        # calculate CMU_JOIN_ID which includes network username and the next highest tiebreaker for that username padded to 6 places
        username = getuser().lower()
        where = '"CMU_JOIN_ID" LIKE'+"'%{0}%'".format(username)
        with arcpy.da.SearchCursor(cmu, 'CMU_JOIN_ID', where_clause = where) as cursor:
            join_ids = sorted({row[0] for row in cursor})
        if len(join_ids) == 0:
            cmu_join_id = username + '000001'
        else:
            t = join_ids[-1]
            tiebreak = str(int(t[-6:])+1).zfill(6)
            cmu_join_id = username + tiebreak

        # test for unsaved edits - alert user to unsaved edits and end script
        try:
            # open editing session and insert new CMU record
            values = [site_name,"D",site_desc,cmu_join_id,geom]
            fields = ["SITE_NAME","STATUS","BRIEF_DESC","CMU_JOIN_ID","SHAPE@"]
            with arcpy.da.InsertCursor(cmu,fields) as cursor:
                cursor.insertRow(values)
        except RuntimeError:
            arcpy.AddWarning("You have unsaved edits in your CMU layer. Please save or discard edits and try again.")
            sys.exit()

######################################################################################################################################################
## Insert species records into CMU species table
######################################################################################################################################################

        SpeciesInsert = []
        # report which EOs were included in CMU and add EO records to list to be inserted into CMU species table
        arcpy.AddMessage("The following species records have been added to the CMU Species Table for CMU with site name, "+site_name+":")
        for eoid in eoids:
            with arcpy.da.SearchCursor(eo_reps, ["ELCODE","ELSUBID","SNAME","SCOMNAME","EO_ID"], '"EO_ID" = {}'.format(eoid)) as cursor:
                for row in cursor:
                    values = tuple([row[0],row[1],row[2],row[3],element_type(row[0]),row[4],cmu_join_id])
                    arcpy.AddMessage(values)
                    SpeciesInsert.append(values)
        arcpy.AddMessage("......")

        # insert EO records into CMU species table
        for insert in SpeciesInsert:
            with arcpy.da.InsertCursor(spec_tbl, ["ELCODE","ELSUBID","SNAME","SCOMNAME","ELEMENT_TYPE","EO_ID","CMU_JOIN_ID"]) as cursor:
                cursor.insertRow(insert)

        # report about EOs that overlap the CMU, but were not included in the CMU species table
        eo_reps_full = arcpy.MakeFeatureLayer_management(eo_reps,"eo_reps_full")
        arcpy.SelectLayerByLocation_management(eo_reps_full,"INTERSECT",temp_cmu,selection_type="NEW_SELECTION")
        arcpy.AddWarning("The following EO rep records intersected your CMU, but do not have a CPP drawn:")
        with arcpy.da.SearchCursor(eo_reps_full,["EO_ID","SNAME","SCOMNAME","LASTOBS_YR","EORANK","EO_TRACK","EST_RA","PREC_BCD"]) as cursor:
            for row in cursor:
                if row[0] not in eoids:
                    arcpy.AddWarning(row)
                else:
                    pass

        arcpy.AddMessage("......")
        arcpy.AddMessage("The initial CMU was created for site name, "+site_name+". Please make any necessary manual edits. Once spatial edits are complete, don't forget to run step 2. Fill CMU Spatial Attributes")

######################################################################################################################################################
## Begin fill CMU spatial attributes tool which finishes attributes that depend on manual edits
######################################################################################################################################################

class FillAttributes(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "2 Fill CMU Spatial Attributes"
        self.description = ""
        self.canRunInBackground = False

    def getParameterInfo(self):
        cmu = arcpy.Parameter(
            displayName = "Selected CMU Layer",
            name = "cmu",
            datatype = "GPFeatureLayer",
            parameterType = "Required",
            direction = "Input")
        cmu.value = r"PGLMT_v2\\CMU"

        pgc_cover = arcpy.Parameter(
            displayName = "PGC Cover Type Layer",
            name = "pgc_cover",
            datatype = "GPFeatureLayer",
            parameterType = "Required",
            direction = "Input")

        params = [cmu,pgc_cover]
        return params

    def isLicensed(self):
        return True

    def updateParameters(self, params):
        return

    def updateMessages(self, params):
        return

    def execute(self, params, messages):

        cmu = params[0].valueAsText
        pgc_cover = params[1].valueAsText

        mem_workspace = "memory"

        # define paths
        username = getuser().lower()
        muni = r'C:\\Users\\'+username+r'\\AppData\\Roaming\\Esri\\ArcGISPro\\Favorites\\StateLayers.Default.pgh-gis0.sde\\StateLayers.DBO.Boundaries_Political\\StateLayers.DBO.PaMunicipalities'
        pgl = r'C:\\Users\\'+username+r'\\AppData\\Roaming\\Esri\\ArcGISPro\\Favorites\\StateLayers.Default.pgh-gis0.sde\\StateLayers.DBO.Protected_Lands\\StateLayers.DBO.PGC_StateGameland'
        boundaries_tbl = r"PNHP.DBO.CMU_PoliticalBoundaries"
        cover_tbl = r"PNHP.DBO.PGC_CoverTypes"

        # check for selection on CMU layer and exit if there is no selection
        desc = arcpy.Describe(cmu)
        if not desc.FIDSet == '':
            pass
        else:
            arcpy.AddWarning("No CMUs are selected. Please make a selection and try again.")
            sys.exit()

        # create list of CMU Join IDs for selected CMUs
        with arcpy.da.SearchCursor(cmu,["CMU_JOIN_ID"]) as cursor:
            cmu_selected = sorted({row[0] for row in cursor})

        # start loop to attribute each selected CMU
        for c in cmu_selected:
            arcpy.AddMessage("Attributing CMU: "+c)
            arcpy.AddMessage("......")
            # delete previous records in boundaries table if they have same CMU Join ID
            with arcpy.da.UpdateCursor(boundaries_tbl,["CMU_JOIN_ID"]) as cursor:
                for row in cursor:
                    if row[0] == c:
                        cursor.deleteRow()
            # delete previous records in PGC cover types table if they have same CMU Join ID
            with arcpy.da.UpdateCursor(cover_tbl,["CMU_JOIN_ID"]) as cursor:
                for row in cursor:
                    if row[0] == c:
                        cursor.deleteRow()

            # make feature layer of cmu join id in loop
            sql_query = "CMU_JOIN_ID = '{}'".format(c)
            cmu_lyr = arcpy.MakeFeatureLayer_management(cmu, "cmu_lyr", sql_query)

######################################################################################################################################################
## calculate acres for CMU
######################################################################################################################################################

            # test for unsaved edits - alert user to unsaved edits and end script
            try:
                with arcpy.da.UpdateCursor(cmu_lyr,["ACRES","SHAPE@"]) as cursor:
                    for row in cursor:
                        acres = round(row[1].getArea("GEODESIC","ACRES"),3)
                        row[0] = acres
                        arcpy.AddMessage(c +" Acres: "+str(acres))
                        arcpy.AddMessage("......")
                        cursor.updateRow(row)
            except RuntimeError:
                arcpy.AddWarning("You have unsaved edits in your CMU layer. Please save or discard edits and try again.")
                sys.exit()

######################################################################################################################################################
## attribute boundaries table
######################################################################################################################################################

            # attribute the counties and municipalities based on those that intersect the CMU
            boundary_union = arcpy.Intersect_analysis([muni,pgl],os.path.join(mem_workspace,"boundary_union"))
            boundary_union_lyr = arcpy.MakeFeatureLayer_management(boundary_union,"boundary_union_lyr")
            arcpy.SelectLayerByLocation_management(boundary_union_lyr,"INTERSECT",cmu_lyr,selection_type="NEW_SELECTION")
            MuniInsert = []
            with arcpy.da.SearchCursor(boundary_union_lyr,["CountyName","FullName","NAME"]) as cursor:
                for row in cursor:
                    values = tuple([row[0].title(),row[1],"SGL "+row[2],c])
                    MuniInsert.append(values)
            arcpy.AddMessage(c + " Boundaries: ")
            for insert in MuniInsert:
                with arcpy.da.InsertCursor(boundaries_tbl,["COUNTY","MUNICIPALITY","SGL","CMU_JOIN_ID"]) as cursor:
                    arcpy.AddMessage(insert)
                    cursor.insertRow(insert)
            arcpy.AddMessage("......")

######################################################################################################################################################
## attribute pgc cover table
######################################################################################################################################################

            # tabulate intersection to get percent and cover type that overlaps cmu
            tab_area = arcpy.TabulateIntersection_analysis(cmu_lyr,arcpy.Describe(cmu_lyr).OIDFieldName,pgc_cover,os.path.join(mem_workspace,"tab_area"),"COVER_TYPE")
            # insert name and percent overlap of protected lands
            CoverInsert = []
            with arcpy.da.SearchCursor(tab_area,["COVER_TYPE","PERCENTAGE"]) as cursor:
                for row in cursor:
                    if row[0] is None:
                        pass
                    else:
                        values = tuple([row[0],round(row[1],2),c])
                        CoverInsert.append(values)
            arcpy.AddMessage(c + " Cover Types: ")
            if CoverInsert:
                for insert in CoverInsert:
                    with arcpy.da.InsertCursor(cover_tbl,["COVER_TYPE","PERCENT_","CMU_JOIN_ID"]) as cursor:
                        arcpy.AddMessage(insert)
                        cursor.insertRow(insert)
            else:
                arcpy.AddMessage("No cover types overlap the CMU.")
            arcpy.AddMessage("#########################################################")
            arcpy.AddMessage("#########################################################")

######################################################################################################################################################
######################################################################################################################################################


import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
import gym  # 包含CartPole的平台环境

import matplotlib.pyplot as plt # 绘图

# Hyperparameters
BATCH_SIZE = 32  # 样本数量
LR = 0.01  # 学习率
EPSILON = 0.9  # greedy policy
GAMMA = 0.9  # reward discount
TARGET_REPLACE_ITER = 100  # 目标网络更新频率
MEMORY_CAPACITY = 2000  # 记忆库容量

# 使用gym库中的环境：CartPole，且打开封装
# 在pycharm中可通过两次shift打开全局搜索，找到源码
env = gym.make('CartPole-v0').unwrapped

N_ACTIONS = env.action_space.n  # 杆子动作个数 (2个)
N_STATES = env.observation_space.shape[0]  # 杆子状态个数 (4个)

# 定义Net类 (定义网络)
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()

        self.fc1 = nn.Linear(N_STATES, 30)  # 设置第一个全连接层
        self.fc1.weight.data.normal_(0, 0.1)
        self.out = nn.Linear(30, N_ACTIONS)  # 设置第二个全连接层
        self.out.weight.data.normal_(0, 0.1)

    def forward(self, x):
        x = F.relu(self.fc1(x))  # 使用ReLU
        actions_value = self.out(x)
        return actions_value

class DQN(object):
    def __init__(self):  # 定义DQN的一系列属性
        self.eval_net, self.target_net = Net(), Net()  # 利用Net创建评估网络和目标网络
        self.learn_step_counter = 0  # for target updating
        self.memory_counter = 0  # for storing memory
        self.memory = np.zeros((MEMORY_CAPACITY, N_STATES * 2 + 2))  # 初始化记忆库，一行代表一个transition
        self.optimizer = torch.optim.Adam(self.eval_net.parameters(), lr=LR)  # Adam优化器
        self.loss_func = nn.MSELoss()  # loss(xi, yi)=(xi-yi)^2

    def choose_action(self, x):  # 根据x状态选择动作
        x = torch.unsqueeze(torch.FloatTensor(x), 0)  # 将x转换成32-bit floating point形式，并在dim=0增加维数为1的维度
        if np.random.uniform() < EPSILON:  # 生成随机数，如果小于EPSILON，选择最优动作
            actions_value = self.eval_net.forward(x)  # 通过对评估网络输入状态x，前向传播获得动作值
            action = torch.max(actions_value, 1)[1].data.numpy()  # 输出每一行最大值的索引，并转化为numpy ndarray形式
            np.random.shuffle(action) # 打乱顺序，避免总是选第0个
            action = action[0]  # 输出第0个
        else:  # 随机选择
            action = np.random.randint(0, N_ACTIONS)
        return action  # 返回选择的动作 (0或1)

    def store_transition(self, s, a, r, s_):  # 定义记忆存储函数 (这里输入为一个transition)
        transition = np.hstack((s, [a, r], s_))  # 在水平方向上拼接数组
        # 如果记忆库满了，便覆盖旧的数据
        index = self.memory_counter % MEMORY_CAPACITY  # 获取transition要置入的行数
        self.memory[index, :] = transition  # 置入transition
        self.memory_counter += 1  # memory_counter自加1

    def learn(self):  # 定义学习函数(记忆库已满后开始学习)
        # 目标网络参数更新
        if self.learn_step_counter % TARGET_REPLACE_ITER == 0:  # 每100步触发，实现Fixed Q-targets
            self.target_net.load_state_dict(self.eval_net.state_dict())  # 将评估网络的参数赋给目标网络
        self.learn_step_counter += 1  # 学习步数自加1

        # Experience Replay
        # 在[0, 2000)内随机抽取32个数，可能会重复
        sample_index = np.random.choice(MEMORY_CAPACITY, BATCH_SIZE)
        b_memory = self.memory[sample_index, :]
        b_s = torch.FloatTensor(b_memory[:, :N_STATES])
        b_a = torch.LongTensor(b_memory[:, N_STATES:N_STATES + 1].astype(int))
        b_r = torch.FloatTensor(b_memory[:, N_STATES + 1:N_STATES + 2])
        b_s_ = torch.FloatTensor(b_memory[:, -N_STATES:])

        # 获取32个transition的评估值和目标值，并利用损失函数和优化器进行评估网络参数更新
        q_eval = self.eval_net(b_s).gather(1, b_a)
        # q_next不进行反向传递误差，所以detach
        q_next = self.target_net(b_s_).detach()
        # q_next.max(1)[0]表示只返回每一行的最大值，不返回索引(长度为32的一维张量)；
        # .view()表示把前面所得到的一维张量变成(BATCH_SIZE, 1)的形状；最终通过公式得到目标值
        q_target = b_r + GAMMA * q_next.max(1)[0].view(BATCH_SIZE, 1)

        # 输入32个评估值和32个目标值，使用均方损失函数
        loss = self.loss_func(q_eval, q_target)
        self.optimizer.zero_grad()  # 清空上一步的残余更新参数值
        loss.backward()  # 误差反向传播, 计算参数更新值
        self.optimizer.step()  # 更新评估网络的所有参数

dqn = DQN()

y = np.array([]) # 记录score

for i in range(300):  # 300个episode循环
    print('Episode: %s' % i)
    s = env.reset()  # 重置环境，先reset才能render

    episode_reward_sum = 0  # 初始化该循环对应的episode的总奖励（加速训练）
    score = 0 # 初始化得分

    while True:  # 开始一个episode (每一个循环代表一步)
        env.render()  # 显示实验动画

        a = dqn.choose_action(s)  # 输入该步对应的状态s，选择动作
        s_, r, done, info = env.step(a)  # 执行动作，获得反馈

        # 修改奖励 根据x的偏离和theta的角度差打分
        x, x_dot, theta, theta_dot = s_
        r1 = (env.x_threshold - abs(x)) / env.x_threshold - 0.8
        r2 = (env.theta_threshold_radians - abs(theta)) / env.theta_threshold_radians - 0.5
        new_r = r1 + r2

        score += 1

        dqn.store_transition(s, a, new_r, s_)  # 存储

        episode_reward_sum += new_r

        s = s_  # 更新状态

        if dqn.memory_counter > MEMORY_CAPACITY:  # 如果累计的transition数量超过了记忆库的固定容量2000
            # 开始学习 (抽取32个transition，并对评估网络参数进行更新
            # 并在开始学习后每隔100次将评估网络的参数赋给目标网络)
            dqn.learn()

        if done:  # 如果done为True
            print('episode%s -- reward_sum: %s' % (i, score))
            break  # 该episode结束

    y = np.append(y, episode_reward_sum)

x = np.arange(0, 300) # x坐标

plt.title("Result")
plt.plot(x, y, color="red") # 绘图
plt.show()


import numpy as np
import cv2
from sklearn.externals import joblib

contMLP=0
contKNN=0
cap = cv2.VideoCapture(0)

while(1):
    ret,frame = cap.read()
    frame_resize = cv2.resize(frame,(100,100), interpolation = cv2.INTER_AREA)
    cv2.imshow("img",frame_resize)
    gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    blur = cv2.medianBlur(gray,7)
    ret,edges = cv2.threshold(blur,0,300,cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
    #edges = cv2.adaptiveThreshold(blur,230,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,11,2)
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
    edges= cv2.morphologyEx(edges, cv2.MORPH_OPEN, kernel)
    #cv2.imshow("edges",edges)
    #cv2.waitKey(0)

    drawing = np.zeros(frame.shape,np.uint8)

    contours, hierarchy = cv2.findContours(edges.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    draw = cv2.drawContours(frame,contours,-1,(0,0,255),3)
    #cv2.imshow("contours",draw)
    #cv2.waitKey(0)
    for component in zip(contours,hierarchy):
        currentContour = component[0]
        x,y,w,h = cv2.boundingRect(currentContour)
        #print(x,y,w,h)
        p = cv2.arcLength(currentContour,True)
        epsilon = 0.015*p
        approx = cv2.approxPolyDP(currentContour,epsilon,True)
        lados = len(approx)
        #print(lados)
        #cv2.imshow("lados", draw)
        #cv2.waitKey(0)

        empty = np.zeros((h,w),np.uint8)
        cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),1)
        #print(w,h)
        roi= edges[y:y+h,x:x+w]
        empty[0:h,0:w]=roi
        #cv2.imshow("roi",roi)
        cv2.imshow("edges", edges)
        cv2.waitKey(0)
        edges = empty
        #cv2.imshow("empty", edges)
        #cv2.waitKey(0)
        img_resize = cv2.resize(edges,(100,100), interpolation = cv2.INTER_AREA)
        ret, edges_res = cv2.threshold(img_resize,0,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        #cv2.imshow("img_resize",img_resize)
        #cv2.waitKey(0)

        contours_2,hierarchy_2 = cv2.findContours(edges_res.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
        hier = hierarchy[0]
        contornos=hier.shape[0]
cv2.destroyAllWindows()


from flask import Flask
from Models.User import User
from config import session_key, app_config, jwt_secret
from Controllers import AuthRoutes, ErrorRoutes, ReviewRoutes, BookRoutes
from Services.Database.database_monoengine import db
from flask_jwt_extended import JWTManager
from flask_login import LoginManager
from flask_mongoengine import MongoEngine

'''
Basic start up of application
Database gets imported then configured and injected in the lifetime of the application
Jwt configuration for authentication and authorization
'''

app = Flask(__name__)

# app settings
app.secret_key = session_key
app.static_folder = app_config['ROOT_PATH'] + '/Views/static'
app.template_folder = app_config['ROOT_PATH'].split('Controllers')[0] + '/Views/templates'

# blueprints init
blueprints = [
    ErrorRoutes.mod,
    AuthRoutes.mod,
    ReviewRoutes.mod,
    BookRoutes.mod

]

for bp in blueprints:
    app.register_blueprint(bp)

# db stuff
app.config['MONGODB_SETTINGS'] = {
    'db': 'bookreview',
    'host': 'mongodb://localhost/mybookreview'
}
app.url_map.strict_slashes = False

login_manager = LoginManager()
db.init_app(app)
login_manager.init_app(app)
login_manager.login_view = 'auth_routes.login'
@login_manager.user_loader
def load_user(user_id):
    return User.objects(id=user_id).first()

# jwt stuff
app.config['JWT_SECRET_KEY'] = jwt_secret
app.config['JWT_TOKEN_LOCATION'] = ['cookies']
jwt = JWTManager(app)

if __name__ == '__main__':
    app.run(host="localhost", port=5010, debug=True)


import os
from pathlib import Path
from typing import Annotated

from fastapi import Form, HTTPException, Request, UploadFile, status
from sqlalchemy.orm import Session

from src.models.post import Post
from src.schemas.post import SelectedPost
from src.utils.currunt_user_id import get_current_user_id

IMGDIR = "images"

SECRET_KEY = os.environ.get("SECRET_KEY")
ALGORITHM = os.environ.get("ALGORITHM")

async def create_post(
    request: Request,
    location: Annotated[str, Form()],
    caption: Annotated[str, Form()],
    image: UploadFile,
    db: Session,
):
    user_id = get_current_user_id(request)
    data = await image.read()
    content_type = image.content_type
    filename = image.filename

    if not content_type == "image/jpeg":
        raise HTTPException(status_code=403, detail="Invalid format")

    # Create the folder if it doesn't exist
    Path(IMGDIR).mkdir(parents=True, exist_ok=True)

    with open(os.path.join(IMGDIR, filename), "wb") as my_file:
        my_file.write(data)
    new_post = Post(location=location, caption=caption, image=filename, user_id=user_id)

    db.add(new_post)
    db.commit()
    db.refresh(new_post)
    return {"Message": "Post Created"}

def get_all_post(request: Request, db: Session):
    all_post = db.query(Post).all()
    return all_post

def post_by_id(id: int, request: Request, db: Session):
    post = db.query(Post).get(id)
    with open(os.path.join(IMGDIR, post.image), "rb") as my_file:
        my_file.read()
    if not post:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="Post not found"
        )
    return post

def post_with_user_(request: Request, db: Session):
    posts = db.query(Post).all()
    for post in list(posts):
        post.__dict__.update({"username": post.users.username})
    if not posts:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="Post not found"
        )
    return posts

def post_user(request: Request, db: Session):
    posts = db.query(Post).all()
    post_list = []
    for post in posts:
        post_dict = {}
        post_dict["username"] = post.users.username
        post_dict["post"] = post
        post_list.append(post_dict)

    if not posts:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="Post not found"
        )
    return post_list

def delete_post(id: int, request: Request, db: Session):
    post = db.query(Post).get(id)
    if not post:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="Post not found"
        )
    db.delete(post)
    db.commit()
    return {"message": "Post Deleted"}

def delete_all_post(request: Request, post: SelectedPost, db: Session):
    for id in post.ids:
        post = db.query(Post).get(id)
        if post:
            db.delete(post)
            db.commit()
    return {"message": "Selected Posts Deleted"}


# -*- encoding: utf-8 -*-
r'''
This program patches xp.exe to be able to handle the new
SHELXL commands RIGU and ABIN.
The program is compatible with Python version 2.3.5 up to 3.4.1.
Feel free to do anything you like with this code.

Use it as "c:\bn\python\python.exe xp_patch.py c:\bn\SXTL\xp.exe"
The original executable will be backed up as "xp.exe.bak"

Daniel Kratzert
dkratzert@gmx.de
'''
import shutil
import sys

try:
    filename = sys.argv[1]
except(IndexError):
    print('Please give the xp ececutable as argument.')
    print('\nfor exmple:\nc:\\bn\\SXTL>xppatch xp.exe')
    sys.exit()

def backup_file(filename):
    try:
        shutil.copyfile(filename, filename + '.bak')
    except(IOError):
        print(('Unable to make backup file from {}.'.format(filename)))
        sys.exit(-1)

try:
    f = open(filename, 'rb+')
except(IOError):
    print('can not open file', filename)
    sys.exit()

binary = f.read()
version = 'XP - Interactive Molecular Graphics'
xp = binary.find(version.encode())
absacta = binary.find('ABSCACTAAFLS'.encode())  # need this as anchor, because
                                                # there are a lot of TIME in xp
hope = binary.find('HOPE'.encode(), absacta + 1)
time = binary.find('TIME'.encode(), absacta + 1)

if xp == -1 or xp < 1000: # don't patch myself
    print('This is not "{}"'.format(version))
    sys.exit()

if hope == -1:
    print('File seems already be patched.')
    sys.exit()

backup_file(filename)

f.seek(hope, 0)
com = f.read(4)
command = com.decode('ascii')
if command == 'HOPE':
    f.seek(hope, 0)
    f.write('RIGU'.encode()) # patch rigu
    print(('RIGU successfully patched'))
else:
    print('no HOPE to patch found')

f.seek(time, 0)
com = f.read(4)
command = com.decode('ascii')
if command == 'TIME':
    f.seek(time, 0)
    f.write('ABIN'.encode()) # patch abin
    print(('ABIN successfully patched'))
else:
    print('no TIME to patch found')


#!/usr/bin/python3
#-*- coding: utf-8 -*-

'''
Apriori and FP-Growth algorithm using external library MLxtend
This file is for testing purpose only,
my original implement please see apriori.py and fp_growth.py

@Version: MLxtend
@Author: Meiying Chen
@Date: 2019-10-16 20:33:18
@LastEditTime: 2019-10-17 10:40:22
'''

# With much love~

import pandas as pd
from mlxtend import preprocessing, frequent_patterns

def apriori(trans:list, min_supp:float, min_conf:float, rules=False):

    te = preprocessing.TransactionEncoder()
    te_ary = te.fit(trans).transform(trans)
    df = pd.DataFrame(te_ary, columns=te.columns_)
    frequent_itemsets = frequent_patterns.apriori(df, min_support=min_supp, use_colnames=True)
    if rules:
        rules = frequent_patterns.association_rules(frequent_itemsets, min_threshold=min_conf)
    else:
        rules = ['rules not required']

    return frequent_itemsets, rules

def fp_growth(trans:list, min_supp:float, max_len=None):

    te = preprocessing.TransactionEncoder()
    te_ary = te.fit(trans).transform(trans)
    df = pd.DataFrame(te_ary, columns=te.columns_)
    frequent_itemsets = frequent_patterns.fpgrowth(df, min_support=min_supp, use_colnames=True, max_len=max_len)

    return frequent_itemsets


# 33-dars.files. uy ishi

# filename='new_file2.txt'
# ism="Qo'ylibek"
# familiya="Jovdarov"
# tyil='2006'
# with open(filename,'w') as file:
#     file.write(ism+' ')
#     file.write(familiya+'\n')
#     file.write(tyil)

# filename='pi_5000.txt'

# with open(filename) as file:
#     pi=file.read()

# pi=pi.rstrip() # qator ohiridagi bo'shliqlarni olib tashlaymiz
# pi =pi.replace('\n','') # qator tashlash belgisini almashtiramiz
# pi =pi.replace(' ','')

# bdate = '16081995'
# if bdate in pi:
#     print("Sizning tug'ilgan sanangiz ushbu raqamlar ichida mavjud.")
# else:
#     print("Afsuski, bu sana ushbu raqamlar ichida mavjud emas")

# pi = float(pi) # matnni float (o'nlik) songa o'tkazamiz

# import pickle
# with open('pi_5000','wb') as file:
#     pickle.dump(pi,file)

while True:
    savol=input("What is your favorite color ? <<< To stop this execution please press 0 >>> ")
    if savol==str(0):
        break
    else:
        with open('new_file3.txt','a') as file:
            file.write(savol+'\n')


from fastapi import FastAPI
from datetime import datetime
from typing import List

app = FastAPI()

# Classes
class Cuenta:
    def __init__(self, numero, dueno, saldo, contactos):
        self.numero = numero
        self.dueno = dueno
        self.saldo = saldo
        self.contactos = contactos
        self.operaciones = []

class Operacion:
    def __init__(self, numero_origen, numero_destino, fecha, valor):
        self.numero_origen = numero_origen
        self.numero_destino = numero_destino
        self.fecha = fecha
        self.valor = valor

# List<Cuenta> BD = new List<Cuenta>();
BD = []
BD.append(Cuenta("21345", "Arnaldo", 200, ["123", "456"]))
BD.append(Cuenta("123", "Luisa", 400, ["456"]))
BD.append(Cuenta("456", "Andrea", 300, ["21345"]))

# Functions
def buscar_dueno(numero_de_cuenta):
    for cuenta in BD:
        if cuenta.numero == numero_de_cuenta:
            return cuenta.dueno

# Endpoints
@app.get("/")
def home():
    return "Everything is working!"

@app.get("/billetera/contactos")
def obtener_contactos(minumero: str):
    for cuenta in BD:
        if cuenta.numero == minumero:
            contactos = {}
            for contacto_numero in cuenta.contactos:
                contacto_dueno = buscar_dueno(contacto_numero)
                contactos[contacto_numero] = contacto_dueno
            return contactos

    return {"mensaje": "No se encontró la cuenta"}

@app.post("/billetera/pagar")
def pagar(minumero: str, numerodestino: str, valor: int):
    cuenta_origen = None
    cuenta_destino = None

    for cuenta in BD:
        if cuenta.numero == minumero:
            cuenta_origen = cuenta
        elif cuenta.numero == numerodestino:
            cuenta_destino = cuenta

    if cuenta_origen is None:
        return {"mensaje": "No se encontró la cuenta origen"}

    if cuenta_destino is None:
        return {"mensaje": "No se encontró la cuenta destino"}

    if cuenta_origen.saldo < valor:
        return {"mensaje": "No tiene saldo suficiente"}

    cuenta_origen.saldo -= valor
    cuenta_destino.saldo += valor

    fecha = datetime.now()
    operacion = Operacion(minumero, numerodestino, fecha, valor)
    cuenta_origen.operaciones.append(operacion)
    cuenta_destino.operaciones.append(operacion)

    return {"mensaje": "Pago exitoso", "fecha": f"Realizado en {fecha}"}

@app.get("/billetera/historial")
def get_historial(minumero: str):
    for cuenta in BD:
        if cuenta.numero == minumero:
            if cuenta.operaciones == []:
                return {"mensaje": "No hay operaciones"}

            historial = []
            saldo_actual = cuenta.saldo

            operaciones = []
            for operacion in cuenta.operaciones:
                if operacion.numero_origen == minumero:
                    tipo_operacion = 'Pago realizado'
                    detalle_operacion = f'a {buscar_dueno(operacion.numero_destino)}'
                    monto_operacion = operacion.valor
                else:
                    tipo_operacion = 'Pago recibido'
                    detalle_operacion = f'de {buscar_dueno(operacion.numero_origen)}'
                    monto_operacion = operacion.valor

                fecha_operacion = operacion.fecha.strftime("%d/%m/%Y %H:%M:%S")
                operaciones.append(f'{tipo_operacion} {detalle_operacion} por {monto_operacion} el {fecha_operacion}')
            historial.append({f'Saldo de {cuenta.dueno}': saldo_actual, f'Operaciones de {cuenta.dueno}': operaciones})
            return historial

    return {"mensaje": "No se encontró la cuenta"}


import click
import dateparser
from typing import Dict

import constants
from flask import Flask
from menu import get_menu
from menu.recipes import get_recipe
from utils import cache

app = Flask(__name__)
cache.init_app(app)

@click.command()
@click.argument("when", default="today")
def menu(when: str) -> None:
    date = dateparser.parse(when)
    lunch_menu, dinner_menu = get_menu(date)
    for i, day in enumerate(constants.DAYS):
        print(f"* {day}")
        print(f"  Lunch: {lunch_menu[i]}")
        print(f"  Dinner: {dinner_menu[i]}")
        if i < 6:
            print()

@click.command()
@click.argument("when", default="today")
def groceries(when: str) -> None:
    date = dateparser.parse(when)
    lunch_menu, dinner_menu = get_menu(date)
    all_recipes = {
        name: get_recipe(name)
        for name in (list(lunch_menu) + list(dinner_menu))
    }
    shopping_list: Dict[str, int] = {}
    for recipe_name, recipe in all_recipes.items():
        if len(recipe.ingredients) == 0:
            print(
                f"WARNING: recipe {recipe_name} does not have any ingredients"
            )
        for ingredient in recipe.ingredients:
            name = ingredient.name.lower()
            if name not in shopping_list.keys():
                shopping_list[name] = 0
            shopping_list[name] += 1
    for ingredient in sorted(shopping_list.keys()):
        print(f"{ingredient}: {shopping_list[ingredient]}")


# Program for Arithmetic Shift Right

def ashr(number):
    k=[]
    k.append(number[0])
    for x in range(0,len(number)-1):
        k.append(number[x])
    ans = ''.join(k)
    return ans

if __name__ == '__main__':

    b = '10001'
    b_list = b.split()
    print(f'The actual number: {b}')
    print(ashr(b))


import pygame
import random

# Constants
WIDTH = 800
HEIGHT = 600
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAVITY = 0.2

class Particle:
    def __init__(self, x, y, size, color):
        self.x = x
        self.y = y
        self.size = size
        self.color = color
        self.vx = random.uniform(-1, 1)
        self.vy = random.uniform(-1, 1)

    def update(self):
        self.vy += GRAVITY
        self.x += self.vx
        self.y += self.vy

        if self.y + self.size >= HEIGHT:
            self.y = HEIGHT - self.size
            self.vy *= -0.9

        if self.x <= 0 or self.x + self.size >= WIDTH:
            self.vx *= -1

    def draw(self, screen):
        pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), self.size)

def main():
    pygame.init()
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    pygame.display.set_caption("Gravity Simulation")
    clock = pygame.time.Clock()

    particles = []
    for _ in range(100):
        x = random.randint(0, WIDTH)
        y = random.randint(0, HEIGHT)
        size = random.randint(5, 20)
        color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
        particle = Particle(x, y, size, color)
        particles.append(particle)

    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

        screen.fill(BLACK)

        for particle in particles:
            particle.update()
            particle.draw(screen)

        pygame.display.flip()
        clock.tick(60)

    pygame.quit()

if __name__ == '__main__':
    main()


from abc import ABCMeta, abstractmethod
import random
import torch
import cv2
from ..transform.mosaic import merge_bboxes
import numpy as np
from torch.utils.data import Dataset
from ..transform import Pipeline

class BaseDataset(Dataset, metaclass=ABCMeta):
    """
    A base class of detection dataset. Referring from MMDetection.
    A dataset should have images, annotations and preprocessing pipelines
    NanoDet use [xmin, ymin, xmax, ymax] format for box and
     [[x0,y0], [x1,y1] ... [xn,yn]] format for key points.
    instance masks should decode into binary masks for each instance like
    {
        'bbox': [xmin,ymin,xmax,ymax],
        'mask': mask
     }
    segmentation mask should decode into binary masks for each class.

    :param img_path: image data folder
    :param ann_path: annotation file path or folder
    :param use_instance_mask: load instance segmentation data
    :param use_seg_mask: load semantic segmentation data
    :param use_keypoint: load pose keypoint data
    :param load_mosaic: using mosaic data augmentation from yolov4
    :param mode: train or val or test
    """

    def __init__(self,
                 img_path,
                 ann_path,
                 input_size,
                 pipeline,
                 keep_ratio=True,
                 use_instance_mask=False,
                 use_seg_mask=False,
                 use_keypoint=False,
                 load_mosaic=False,
                 mixup=False,
                 mode='train'
                 ):
        self.img_path = img_path
        self.ann_path = ann_path
        self.input_size = input_size
        self.pipeline = Pipeline(pipeline, keep_ratio)
        self.keep_ratio = keep_ratio
        self.use_instance_mask = use_instance_mask
        self.use_seg_mask = use_seg_mask
        self.use_keypoint = use_keypoint
        self.load_mosaic = load_mosaic
        self.mixup = mixup
        self.mode = mode

        self.data_info = self.get_data_info(ann_path)
        self.indices = list(range(len(self.data_info)))
        # print(self.indices)

    def __len__(self):
        return len(self.data_info)

    def get_valid_train_data(self, idx):
        while True:
            data = self.get_train_data(idx)
            if data is None:
                idx = self.get_another_id()
                continue
            else:
                return data

    def get_mosaic(self, idx):
        data = self.get_valid_train_data(idx)
        w, h = self.input_size
        # print(self.input_size)
        min_offset = 0.2
        cut_x = np.random.randint(
            int(w*min_offset), int(w*(1 - min_offset)))
        cut_y = np.random.randint(
            int(h*min_offset), int(h*(1 - min_offset)))
        data0 = data
        random_index = random.sample(self.indices, 3)
        data1 = self.get_valid_train_data(random_index[0])
        data2 = self.get_valid_train_data(random_index[1])
        data3 = self.get_valid_train_data(random_index[2])
        d1 = data0['img'][:, :cut_y, :cut_x]
        d2 = data1['img'][:, cut_y:, :cut_x]
        d3 = data2['img'][:, cut_y:, cut_x:]
        d4 = data3['img'][:, :cut_y, cut_x:]

        tmp1 = torch.cat([d1, d2], 1)
        tmp2 = torch.cat([d4, d3], 1)
        mosaic_img = torch.cat([tmp1, tmp2], 2)

        labels, boxes = merge_bboxes([data0['gt_bboxes'], data1['gt_bboxes'], data2['gt_bboxes'], data3['gt_bboxes']], [
            data0['gt_labels'], data1['gt_labels'], data2['gt_labels'], data3['gt_labels']], cut_x, cut_y, w, h)
        # print(data['gt_labels'])
        # print('before:',data['gt_labels'].dtype)
        data['gt_labels'] = np.array(labels, dtype=np.int64)
        data['gt_bboxes'] = np.array(boxes, dtype=np.float32).reshape(-1, 4)
        data['img'] = mosaic_img
        return data

    def __getitem__(self, idx):
        if self.mode == 'val' or self.mode == 'test':
            return self.get_val_data(idx)
        else:
            if self.load_mosaic:
                data = self.get_mosaic(idx)
            else:
                data = self.get_valid_train_data(idx)

            if self.mixup and random.random() < 0.5:
                if self.load_mosaic:
                    data1 = self.get_mosaic(self.get_another_id())
                else:
                    data1 = self.get_valid_train_data(self.get_another_id())

                r = np.random.beta(8.0, 8.0)  # mixup ratio, alpha=beta=8.0
                data['img'] = data['img'] * r + data1['img'] * (1 - r)
                data['gt_labels'] = np.concatenate([data['gt_labels'],data1['gt_labels']])
                data['gt_bboxes'] = np.concatenate([data['gt_bboxes'],data1['gt_bboxes']])

            return data

    @abstractmethod
    def get_data_info(self, ann_path):
        pass

    @abstractmethod
    def get_train_data(self, idx):
        pass

    @abstractmethod
    def get_val_data(self, idx):
        pass

    def get_another_id(self):
        return np.random.random_integers(0, len(self.data_info)-1)


# -*- coding: utf-8 -*-
#!/usr/bin/env python

import os
import sys

import custom_user

try:
    from setuptools import setup
except ImportError:
    from distutils.core import setup

version = custom_user.__version__

if sys.argv[-1] == 'publish':
    os.system('python setup.py sdist bdist_wheel upload')
    print("You probably want to also tag the version now:")
    print("  git tag -a %s -m 'version %s'" % (version, version))
    print("  git push --tags")
    sys.exit()

readme = open('README.rst').read()

setup(
    name='django-custom-user',
    version=version,
    description="""Custom user model for Django >= 1.5 with the same behaviour as Django's default User but with email instead of username.""",
    long_description=readme,
    author='Josep Cugat',
    author_email='jcugat@gmail.com',
    url='https://github.com/jcugat/django-custom-user',
    packages=[
        'custom_user',
        'custom_user.migrations',
    ],
    include_package_data=True,
    install_requires=[
        "Django >= 1.5",
    ],
    license='BSD License',
    zip_safe=False,
    keywords='django custom user auth model email without username',
    classifiers=[
        'Development Status :: 4 - Beta',
        'Environment :: Web Environment',
        'Framework :: Django',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: BSD License',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
        'Topic :: Internet :: WWW/HTTP',
        'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
    ],
)


listaNum = []

while True:
    numero = int(input('Digite um numero: '))
    if numero not in listaNum:#adicionar numero na lista se ja não tiver o mesmo
        listaNum.append(numero)
    else:
        print('Numero duplicado, não vou adicionar!!!')

    resposta = str(input('Quer continuar [S/N]: '))
    while resposta not in 'SsNn':
        print('Opção invalída, Digite novamente!')
        resposta = str(input('Quer continuar [S/N]: '))

    if resposta in 'Nn':
        break

listaNum.sort()
print('-=' * 20)
print(f'Você digitou os numeros', listaNum)


from karim.secrets import secrets
import telegram.bot
from telegram.ext import messagequeue as mq

class MQBot(telegram.bot.Bot):
    def __init__(self, *args, is_queued_def=True, mqueue=None, **kwargs):
        super(MQBot, self).__init__(*args, **kwargs)
        # below 2 attributes should be provided for decorator usage
        self._is_messages_queued_default = is_queued_def
        self._msg_queue = mqueue or mq.MessageQueue()

    def __del__(self):
        try:
            self._msg_queue.stop()
        except:
            pass

    @mq.queuedmessage
    def send_queued_message(self, *args, **kwargs):
        '''Wrapped method would accept new `queued` and `isgroup`
        OPTIONAL arguments'''
        return super(MQBot, self).send_message(*args, **kwargs)

    def report_error(self, error=None, send_screenshot=False, screenshot_name=''):
        string = str(secrets.get_var('DEVS')).replace('[', '')
        string = string.replace(']', '')
        string = string.replace(' ', '')
        devs = list(string.split(','))
        for dev in devs:
            if send_screenshot:
                self.send_photo(chat_id=int(dev), photo=open('{}.png'.format(screenshot_name), 'rb'), caption='There was an error with the Karim Luman bot: \n{}'.format(error))
            else:
                self.send_message(chat_id=int(dev), text='There was an error with the Karim Luman bot: \n{}'.format(error))


#!/usr/bin/env python
import sys
from math import sqrt

old_aid = None # airline_id
tot_mean = 0
tot_count = 0
tot_var= 0
# Input from stdin (handled via Hadoop Streaming)
for line in sys.stdin:

    # Remove whitespace and split up lines
    line = line.strip()
    line = line.split('\t')
    if len(line) != 4:
        print("badly formatted line %s", str(line))
        continue

    # Get word and count
    aid, dmean, dvar, dcount = line

    try:
        aid = int(aid)
        dcount = int(dcount)
        dmean = float(dmean)
        dvar = float(dvar)
    except ValueError as e:
        print ("Error .. skipping bad line %s \n due to %s ... " % (line,e));
        continue

    if (old_aid is not None) and (old_aid != aid):
        print('%s\t%s\t%s' % (old_aid, tot_mean, sqrt(tot_var)))
        old_aid = None
        tot_mean = 0
        tot_count = 0
        tot_var= 0

    old_aid = aid
    delta = dmean - tot_mean
    tot_mean = (tot_count*tot_mean + dcount*dmean)/(tot_count + dcount)
    tot_sum_squared_deltas = dvar*dcount + tot_var*tot_count + delta ** 2 * (tot_count*dcount)/(tot_count + dcount)
    tot_count += dcount
    tot_var=tot_sum_squared_deltas/tot_count

if old_aid is not None:
    print('%s\t%s\t%s' % (old_aid, tot_mean, sqrt(tot_var)))


from datetime import datetime, timezone
from os import environ
from typing import Callable, List, Optional, Union
from uuid import uuid4

from boto3.dynamodb.conditions import Attr, Key

import dynamo.user
from dynamo.util import DYNAMODB_RESOURCE, convert_floats_to_decimals, format_time, get_request_time_expression

class QuotaError(Exception):
    """Raised when trying to submit more jobs that user has remaining"""

def _get_job_count_for_month(user) -> int:
    now = datetime.now(timezone.utc)
    start_of_month = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
    job_count_for_month = count_jobs(user, format_time(start_of_month))
    return job_count_for_month

def get_quota_status(user) -> Union[tuple[int, int, int], tuple[None, None, None]]:
    max_jobs = dynamo.user.get_max_jobs_per_month(user)

    if max_jobs is not None:
        previous_jobs = _get_job_count_for_month(user)
        remaining_jobs = max(max_jobs - previous_jobs, 0)
    else:
        previous_jobs = None
        remaining_jobs = None

    return max_jobs, previous_jobs, remaining_jobs

def put_jobs(user_id: str, jobs: List[dict], fail_when_over_quota=True) -> List[dict]:
    table = DYNAMODB_RESOURCE.Table(environ['JOBS_TABLE_NAME'])
    request_time = format_time(datetime.now(timezone.utc))

    max_jobs, previous_jobs, remaining_jobs = get_quota_status(user_id)
    has_quota = max_jobs is not None
    if has_quota:
        assert previous_jobs is not None
        assert remaining_jobs is not None

    if has_quota and len(jobs) > remaining_jobs:
        if fail_when_over_quota:
            raise QuotaError(f'Your monthly quota is {max_jobs} jobs. You have {remaining_jobs} jobs remaining.')
        jobs = jobs[:remaining_jobs]

    priority_override = dynamo.user.get_priority(user_id)
    priority = _get_job_priority(priority_override, has_quota)

    prepared_jobs = [
        {
            'job_id': str(uuid4()),
            'user_id': user_id,
            'status_code': 'PENDING',
            'execution_started': False,
            'request_time': request_time,
            'priority': priority(previous_jobs, index),
            **job,
        } for index, job in enumerate(jobs)
    ]

    for prepared_job in prepared_jobs:
        table.put_item(Item=convert_floats_to_decimals(prepared_job))
    return prepared_jobs

def _get_job_priority(priority_override: Optional[int], has_quota: bool) -> Callable[[Optional[int], int], int]:
    if priority_override is not None:
        priority = lambda _, __: priority_override
    elif has_quota:
        priority = lambda previous_jobs, job_index: max(9999 - previous_jobs - job_index, 0)
    else:
        priority = lambda _, __: 0
    return priority

def count_jobs(user, start=None, end=None):
    table = DYNAMODB_RESOURCE.Table(environ['JOBS_TABLE_NAME'])
    key_expression = Key('user_id').eq(user)
    if start is not None or end is not None:
        key_expression &= get_request_time_expression(start, end)

    params = {
        'IndexName': 'user_id',
        'KeyConditionExpression': key_expression,
        'Select': 'COUNT',
    }
    response = table.query(**params)
    job_count = response['Count']
    while 'LastEvaluatedKey' in response:
        params['ExclusiveStartKey'] = response['LastEvaluatedKey']
        response = table.query(**params)
        job_count += response['Count']
    return job_count

def query_jobs(user, start=None, end=None, status_code=None, name=None, job_type=None, start_key=None):
    table = DYNAMODB_RESOURCE.Table(environ['JOBS_TABLE_NAME'])

    key_expression = Key('user_id').eq(user)
    if start is not None or end is not None:
        key_expression &= get_request_time_expression(start, end)

    filter_expression = Attr('job_id').exists()
    if status_code is not None:
        filter_expression &= Attr('status_code').eq(status_code)
    if name is not None:
        filter_expression &= Attr('name').eq(name)
    if job_type is not None:
        filter_expression &= Attr('job_type').eq(job_type)

    params = {
        'IndexName': 'user_id',
        'KeyConditionExpression': key_expression,
        'FilterExpression': filter_expression,
        'ScanIndexForward': False,
    }
    if start_key is not None:
        params['ExclusiveStartKey'] = start_key

    response = table.query(**params)
    jobs = response['Items']
    return jobs, response.get('LastEvaluatedKey')

def get_job(job_id):
    table = DYNAMODB_RESOURCE.Table(environ['JOBS_TABLE_NAME'])
    response = table.get_item(Key={'job_id': job_id})
    return response.get('Item')

def update_job(job):
    table = DYNAMODB_RESOURCE.Table(environ['JOBS_TABLE_NAME'])
    primary_key = 'job_id'
    key = {'job_id': job[primary_key]}

    prepared_job = convert_floats_to_decimals(job)
    update_expression = 'SET {}'.format(','.join(f'{k}=:{k}' for k in prepared_job if k != primary_key))
    expression_attribute_values = {f':{k}': v for k, v in prepared_job.items() if k != primary_key}

    table.update_item(
        Key=key,
        UpdateExpression=update_expression,
        ExpressionAttributeValues=expression_attribute_values,
    )

def get_jobs_waiting_for_execution(limit: int) -> list[dict]:
    table = DYNAMODB_RESOURCE.Table(environ['JOBS_TABLE_NAME'])

    params = {
        'IndexName': 'status_code',
        'KeyConditionExpression': Key('status_code').eq('PENDING'),
        'FilterExpression': Attr('execution_started').ne(True),
    }
    response = table.query(**params)
    jobs = response['Items']

    while 'LastEvaluatedKey' in response and len(jobs) < limit:
        params['ExclusiveStartKey'] = response['LastEvaluatedKey']
        response = table.query(**params)
        jobs.extend(response['Items'])

    return jobs[:limit]


import Tkinter
from mglutil.gui.BasicWidgets.Tk.trees.tree import IconsManager
from mglutil.gui.BasicWidgets.Tk.trees.TreeWithButtons import \
     ColumnDescriptor ,TreeWithButtons, NodeWithButtons

from DejaVu2.Geom import Geom
from DejaVu2.IndexedPolygons import IndexedPolygons
from DejaVu2.IndexedPolylines import IndexedPolylines
from DejaVu2.Polylines import Polylines
from DejaVu2.Spheres import Spheres
from DejaVu2.Cylinders import Cylinders
from DejaVu2.glfLabels import GlfLabels

class DejaVu2GeomTreeWithButtons(TreeWithButtons):
    """
    Class to display a tree for DejaVu2 geoemtry.
    """

    def __init__(self, master, root, iconsManager=None,
                 idleRedraw=True, nodeHeight=18, headerHeight=30,
                 treeWidth=150, **kw):
        # add a compound selector entry
        kw['iconsManager'] = iconsManager
        kw['idleRedraw'] = idleRedraw
        kw['nodeHeight'] = nodeHeight
        kw['headerHeight'] = headerHeight
        kw['treeWidth'] = treeWidth
        TreeWithButtons.__init__( *(self, master, root), **kw )

        canvas = self.canvas

class DejaVu2GeomNode(NodeWithButtons):
    """
    The first level of this tree is either a molecule or a container.
    The second level are geoemtry object. Columns are used to modify geoms
    """

    def getChildren(self):
        """
        return children for object associated with this node.
        By default we return object.children. Override this method to
        selectively show children
        """
        return self.children

    def getIcon(self):
        """
        return node's icons for DejaVu2 geometry objects
        """
        iconsManager = self.tree().iconsManager
        object = self.object

        if isinstance(object, IndexedPolygons):
            icon = iconsManager.get("mesh16.png", self.tree().master)
        elif isinstance(object, IndexedPolylines) or \
                 isinstance(object, Polylines):
            icon = iconsManager.get("lines16.png", self.tree().master)
        elif isinstance(object, Spheres):
            icon = iconsManager.get("spheres16.png", self.tree().master)
        elif isinstance(object, Cylinders):
            icon = iconsManager.get("cyl16.png", self.tree().master)
        elif isinstance(object, GlfLabels):
            icon = iconsManager.get("labels16.png", self.tree().master)
        else: # isinstance(object, Geom):
            icon = iconsManager.get("geom16.png", self.tree().master)

        if icon:
            self.iconWidth = icon.width()
        else:
            self.iconWidth = 0
        return icon

if __name__ == '__main__':
    root = Tkinter.Toplevel()
    vi = self.GUI.VIEWER

    iconsManager = IconsManager(['Icons'], 'DejaVu2')

    rootnode = DejaVu2GeomNode(vi.rootObject, None)

    tree = DejaVu2GeomTreeWithButtons(root, rootnode, self, nodeHeight=18,
                                     iconsManager=iconsManager, headerHeight=0,
                                     treeWidth=180, selectionMode='multiple')
    tree.pack(side='bottom', expand=1, fill='both')
    rootnode.expand()


import random
import socket
import struct
import sys
import numpy as np
import wave

src_addr = 'localhost'
src_port = 8000

stream_id = 8;

def connect():
    """
    Connect to a specific port
    """

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    try:
        sock.connect((src_addr, src_port))
    except:
        print("Error connecting to {}:{}".format(src_addr, src_port))
        return None
    try:
        print("Sending stream info")
        sock.sendall(struct.pack('<iBi', 5, 1, stream_id));
    except:
        print("Error: Stream rejected")
        return None
    print("Successfully connected to host")
    return sock

def decode_frame(raw_frame):
    # The format is given according to the following assumption of network data

    # Expect little endian byte order
    endianness = "<"

    # [ commonTimestamp | frame type | sample count
    header_format = "qii"

    timestamp, frame_type, sample_count = struct.unpack(endianness + header_format, raw_frame[:struct.calcsize(header_format)])

    samples_format = str(sample_count) + "f"
    # Unpack the raw frame into individual pieces of data as a tuple
    frame_pieces = struct.unpack(endianness + samples_format, raw_frame[struct.calcsize(header_format):])

    return (timestamp, frame_type, sample_count, list(frame_pieces))

def recv_all(sock, size):
    result = b''
    while len(result) < size:
        data = sock.recv(size - len(result))
        if not data:
            raise EOFError("Error: Received only {} bytes into {} byte message".format(len(data), size))
        result += data
    return result

def recv_audio_frame(sock):
    """
    To read each stream frame from the server
    """
    (load_size,) = struct.unpack("<i", recv_all(sock, struct.calcsize("<i")))
    #print(load_size)
    return recv_all(sock, load_size)

if __name__ == '__main__':
    s = connect()
    if s is None:
        sys.exit(0)

    sign = lambda x: 1 if x >= 0.0 else -1

    do_write = True if len(sys.argv) > 1 and sys.argv[1] == '--write' else False

    if do_write:
        out_file = sys.argv[2] if len(sys.argv) > 2 else 'out.wav'
        outwav = wave.open(out_file, 'wb')
        outwav.setparams((1, 2, 16000, 0, "NONE", "NONE"))

    while True:
        try:
            f = recv_audio_frame(s)
            timestamp, frame_type, sample_count, samples = decode_frame(f)
            # PCM-16
            samples = [ int(sm * 32767) if -1.0 <= sm <= 1.0 else (sign(sm) * 32767 ) for sm in samples ]
            if do_write:
                outwav.writeframes(struct.pack('<' + str(len(samples)) + 'h', *samples))
            print(timestamp, frame_type, sample_count, random.sample(samples, 5), max(samples))
        except:

            break
        print("\n\n")

    s.close()
    if do_write:
        outwav.close()