#!/usr/bin/python3
import numpy as np
import random

"""
w/ decision tree we want to choose features based on greatest information gain (smallest entropy)

p_dot = P/(P+N)
Entropy: Imp(p_dot) = -p_dot*log_2(p_dot) - (1-p_dot)log_2(1-p_dot)
Combine entropy of branches with weights for total entropy after split
Lowest Entropy & lower than before split = Greatest information gain
We want the feature with greatest information gain
"""

class decisionTree(object):
    def __init__(self):
        self.feature = None
        self.entropy = None
        self.ent1 = None
        self.ent2 = None
        self.left = None
        self.right = None
        self.parent = None
        self.range = None
        self.isLeaf = False
        self.leafVal = None

    def get_range(self):
        return self.range

    def setParent(self, feature, entropy, left, right, parent):
        self.parent = decisionTree()
        self.parent.feature = feature
        self.parent.entropy = entropy
        self.parent.left = left
        self.parent.right = right
        self.parent.parent = None

    def setChildren(self, left, right):
        self.left = left
        self.right = right

    def getIsLeaf(self):
        return self.isLeaf

    def getLeafVal(self):
        return self.leafVal

def get_parents(tree):
    parents = []
    get_parent_helper(tree, parents)
    return parents

def get_parent_helper(tree, parents):
    if tree.parent is not None:
        parents.append(tree.parent)
        get_parent_helper(tree.parent, parents)
    else:
        return parents

def getEntropyBin(c, label):
    onePos = oneNeg = zeroPos = zeroNeg = 0
    size = len(label)
    for i in range(c.size):
        if(c[i] == 1):
            if(label[i] == 1):
                onePos += 1
            else:
                oneNeg += 1
        else:  # c[i]=0
            if(label[i] == 1):
                zeroPos += 1
            else:
                zeroNeg += 1
    if (onePos+oneNeg) != 0:
        onepdot = onePos / float(onePos + oneNeg)
    else:
        onepdot = 0
    if (zeroPos+zeroNeg) != 0:
        zeropdot = zeroPos / float(zeroPos + zeroNeg)
    else:
        zeropdot = 0
    if onepdot == 0 or onepdot == 1:
        oneEnt = 0
    else:
        oneEnt = -onepdot*np.log2(onepdot) - (1-onepdot)*np.log2(1-onepdot)
    if zeropdot == 0 or zeropdot == 1:
        zeroEnt = 0
    else:
        zeroEnt = -zeropdot*np.log2(zeropdot) - \
            (1-zeropdot)*np.log2(1-zeropdot)
    Entropy = oneEnt*(onePos+oneNeg)/size + zeroEnt*(zeroPos+zeroNeg)/size
    return Entropy, 0.5, zeroEnt, oneEnt, zeroPos, zeroNeg, onePos, oneNeg

def getEntropyInt(c, label, idx):
    d = np.sort(c, axis=0, kind="quicksort")
    split = []
    for splitVal in range(len(label)-1):
        split.append((d[splitVal]+d[splitVal+1])/2)
    size = len(label)
    leaf1PosFinal = leaf1NegFinal = leaf2PosFinal = leaf2NegFinal = 0
    smallestEntropy = ent1Final = ent2Final = 1
    splitRange = None
    for splitVal in split:  # iterating through trying to find best split val
        leaf1Pos = leaf1Neg = leaf2Pos = leaf2Neg = 0
        # for each split value calculating all the positive and negative labeled values for leaf1 and leaf2
        for i in range(len(label)):
            # int(c[i])  #if i replace with c again so entropy of floats too high and overall score without using float features, score higher
            if c[i] <= splitVal:
                if(label[i] == 1):  # label says true
                    leaf1Pos += 1
                else:
                    leaf1Neg += 1
            else:  # for leaf 2 when greater than the split value
                if label[i] == 1:  # label says true
                    leaf2Pos += 1
                else:
                    leaf2Neg += 1
        if (leaf1Pos+leaf1Neg) != 0:
            pdot1 = leaf1Pos/float(leaf1Pos+leaf1Neg)
        else:
            pdot1 = 0
        if (leaf2Pos+leaf2Neg) != 0:
            pdot2 = leaf2Pos/float(leaf2Pos+leaf2Neg)
        else:
            pdot2 = 0
        if(pdot1 == 0 or pdot1 == 1):
            ent1 = 0
        else:
            ent1 = -pdot1*np.log2(pdot1) - (1-pdot1)*np.log2(1-pdot1)
        if pdot2 == 0 or pdot2 == 1:
            ent2 = 0
        else:
            ent2 = -pdot2*np.log2(pdot2) - (1-pdot2)*np.log2(1-pdot2)
        Entropy = (ent1 * ((leaf1Pos+leaf1Neg)/size)) + \
            (ent2*((leaf2Pos+leaf2Neg)/size))
        if Entropy < smallestEntropy:
            smallestEntropy = Entropy
            ent1Final,ent2Final = ent1,ent2
            splitRange = splitVal
            leaf1PosFinal,leaf1NegFinal,leaf2PosFinal,leaf2NegFinal = leaf1Pos,leaf1Neg,leaf2Pos,leaf2Neg
    return smallestEntropy, splitRange, ent1Final, ent2Final, leaf1PosFinal, leaf1NegFinal, leaf2PosFinal, leaf2NegFinal

def transformMatrix(c, idx):
    if(idx == 8):
        c = c*2
    if(idx == 9):
        c = c*5
    if(idx == 10):
        c = c*3
    if(idx == 11 or idx == 12):
        c = c*13
    if(idx == 13):
        c = c*13
    if(idx == 14):
        c = c*70
    if(idx == 15):
        c = c*130
    if(idx == 16):
        c = c*3000
    if(idx == 17):
        c = c*3000
    return c

def getEntropyFloat(c, label, idx):
    '''
    sorts c in increasing order and splits inbetween each for the split values to test
    use gain ratio to remove bias for information gain to attributes with a large number of values
    '''
    d = np.sort(c, axis=0, kind="quicksort")
    split = []
    for splitVal in range(len(label)-1):
        split.append((d[splitVal]+d[splitVal+1])/2)
    size = len(label)
    smallestEntropy = 1
    ent1Final = ent2Final = splitRange = None
    leaf1PosFinal = leaf1NegFinal = leaf2PosFinal = leaf2NegFinal = 0
    for splitVal in split:  # iterating through trying to find best split val
        leaf1Pos = leaf1Neg = leaf2Pos = leaf2Neg = 0
        # for each split value calculating all the positive and negative labeled values for leaf1 and leaf2
        for i in range(len(label)):
            if c[i] <= splitVal:
                if label[i] == 1:  # label says true
                    leaf1Pos += 1
                else:
                    leaf1Neg += 1
            else:  # for leaf 2 when greater than the split value
                if label[i] == 1:  # label says true
                    leaf2Pos += 1
                else:
                    leaf2Neg += 1
        if (leaf1Pos+leaf1Neg) != 0:
            pdot1 = leaf1Pos/float(leaf1Pos+leaf1Neg)
        else:
            pdot1 = 0
        if (leaf2Pos+leaf2Neg) != 0:
            pdot2 = leaf2Pos/float(leaf2Pos+leaf2Neg)
        else:
            pdot2 = 0
        if pdot1 == 0 or pdot1 == 1:
            ent1 = 0
        else:
            ent1 = -pdot1*np.log2(pdot1) - (1-pdot1)*np.log2(1-pdot1)
        if pdot2 == 0 or pdot2 == 1:
            ent2 = 0
        else:
            ent2 = -pdot2*np.log2(pdot2) - (1-pdot2)*np.log2(1-pdot2)
        Entropy = (ent1 * ((leaf1Pos+leaf1Neg)/size)) + \
            (ent2*((leaf2Pos+leaf2Neg)/size))
        if Entropy < smallestEntropy:
            smallestEntropy = Entropy
            ent1Final,ent2Final = ent1,ent2
            splitRange = splitVal
            leaf1PosFinal,leaf1NegFinal,leaf2PosFinal,leaf2NegFinal = leaf1Pos,leaf1Neg,leaf2Pos,leaf2Neg
    return smallestEntropy, splitRange, ent1Final, ent2Final, leaf1PosFinal, leaf1NegFinal, leaf2PosFinal, leaf2NegFinal

def getNewData(train_data, train_labels, bestFeature, rnge, section):
    '''
    to get smaller matrix
    section is 0 or 1
      if 0 means this is left tree so we are comparing <= range and removing greater than range
      if section 1 means we are comparing greater range and removing <= range
    '''
    c = train_data.T[bestFeature]  # column
    # td = transformMatrix(c,bestFeature) #column of bestfeature all transformed just incase it is float
    removeRows = []
    if(section == 0):
        for i in range(train_labels.size):
            if(c[i] > rnge):
                # because will remove these indexes to only get remaining ones on left
                removeRows.append(i)
    else:  # section1
        # so will go through every row of the training data
        for i in range(train_labels.size):
            if c[i] <= rnge:
                removeRows.append(i)
    train_data_new = np.delete(train_data, removeRows, 0)
    train_labels_new = np.delete(train_labels, removeRows, 0)
    return train_data_new, train_labels_new

def build(tree, train_data, train_labels, flg, forestfeatures):
    '''
    flg
    -0 for being built off left attribute
    -1 for being built off right attribute
    '''
    forestfeatures=set(forestfeatures)
    '''
    parents = get_parents(tree)
    parentsList = []
    for parent in parents:
        parentsList.append(parent.feature)
    '''
    if flg == 2:
        Ent1BeforeSplit = Ent2BeforeSplit = 1
    else:
        Ent1BeforeSplit = tree.parent.ent1
        Ent2BeforeSplit = tree.parent.ent2
    minEntropy = 1
    bestFeature = -1
    leaf1PosFinal = leaf1NegFinal = leaf2PosFinal = leaf2NegFinal = thernge = 0
    earlyStop = 20  # 4
    ent1Final = ent2Final = 1
    for i in range(train_data[0].size):  # length of a row
        # if(i not in parentsList): #save time because woudn't need feature already used by parent (maybe ignore this and allow more splits but a lot worse runtime
        c = train_data.T[i]  # a column
        if (i <= 1 or i == 18) and i in forestfeatures:
            entro, rnge, leaf1Entropy, leaf2Entropy, leaf1Pos, leaf1Neg, leaf2Pos, leaf2Neg = getEntropyBin(
                c, train_labels)
        elif (i >= 2 and i <= 7) and i in forestfeatures:
            entro, rnge, leaf1Entropy, leaf2Entropy, leaf1Pos, leaf1Neg, leaf2Pos, leaf2Neg = getEntropyInt(
                c, train_labels, i)
        elif i in forestfeatures:
            entro, rnge, leaf1Entropy, leaf2Entropy, leaf1Pos, leaf1Neg, leaf2Pos, leaf2Neg = getEntropyFloat(
                c, train_labels, i)
        else:
            # not in forestfeature list so don't use (random forests implementation)
            continue
        if entro < minEntropy:
            minEntropy = entro
            thernge = rnge
            bestFeature = i
            leaf1PosFinal,leaf1NegFinal,leaf2PosFinal,leaf2NegFinal = leaf1Pos,leaf1Neg,leaf2Pos,leaf2Neg
            ent1Final,ent2Final = leaf1Entropy,leaf2Entropy

    # left branch so compare with left entropy before split
    if flg == 0 and minEntropy > Ent1BeforeSplit:
        tree.isLeaf = True
        if(leaf1PosFinal+leaf2PosFinal > leaf1NegFinal + leaf2NegFinal):
            tree.leafVal = 1
        else:
            tree.leafVal = 0
        return
    elif flg == 1 and minEntropy > Ent2BeforeSplit:
        tree.isLeaf = True
        if leaf1PosFinal+leaf2PosFinal > leaf1NegFinal + leaf2NegFinal:
            tree.leafVal = 1
        else:
            tree.leafVal = 0
        return
    else:
        tree.feature = bestFeature
        tree.entropy = minEntropy
        tree.ent1,tree.ent2 = ent1Final,ent2Final
        tree.range = thernge
    if leaf1PosFinal > leaf1NegFinal:
        leaf1Prob = 1
    else:
        leaf1Prob = 0
    if leaf2PosFinal > leaf2NegFinal:
        leaf2Prob = 1
    else:
        leaf2Prob = 0
    if minEntropy == 0:  # both will be leaves
        #print("both leaf1 and leaf2 leaves entrop 0 early stop")
        tree.left = decisionTree()
        tree.left.parent = tree
        tree.left.isLeaf = True
        tree.left.leafVal = leaf1Prob

        tree.right = decisionTree()
        tree.right.parent = tree
        tree.right.isLeaf = True
        tree.right.leafVal = leaf2Prob
    else:
        if leaf1PosFinal+leaf1NegFinal < earlyStop or ent1Final == 0:
            if leaf2PosFinal+leaf2NegFinal < earlyStop or ent2Final == 0:  # both leaves
                #print("leaf1&2 early stop")
                leafLeft = decisionTree()
                leafLeft.isLeaf = True
                leafLeft.leafVal = leaf1Prob
                leafRight = decisionTree()
                leafRight.isLeaf = True
                leafRight.leafVal = leaf2Prob
                tree.left = leafLeft
                tree.right = leafRight
                leafLeft.parent = tree
                leafRight.parent = tree
            else:  # only left side leaf
                #print("only leaf1 early stop")
                leafLeft = decisionTree()
                leafLeft.isLeaf = True
                leafLeft.leafVal = leaf1Prob
                tree.left = leafLeft
                leafLeft.parent = tree
                tree.right = decisionTree()
                tree.right.parent = tree
                trainData, trainLabels = getNewData(train_data, train_labels, bestFeature, tree.range, 1)  # updates Matrix
                build(tree.right, trainData, trainLabels, 1, forestfeatures)
        else:  # first part not leaf
            if leaf2PosFinal+leaf2NegFinal < earlyStop or ent2Final == 0:  # only right side leaf
                #print("only leaf2 early stop")
                leafRight = decisionTree()
                leafRight.isLeaf = True
                leafRight.leafVal = leaf2Prob
                tree.right = leafRight
                tree.left = decisionTree()
                tree.left.parent = tree

                trainData, trainLabels = getNewData(
                    train_data, train_labels, bestFeature, tree.range, 0)  # updates Matrix
                build(tree.left, trainData, trainLabels, 0, forestfeatures)
            else:  # both aren't leaves
                #print("no early stop for either leaves")
                tree.left = decisionTree()
                tree.left.parent = tree
                tree.right = decisionTree()
                tree.right.parent = tree
                trainDataOne, trainLabelsOne = getNewData(
                    train_data, train_labels, bestFeature, tree.range, 0)  # updates Matrix
                trainDataTwo, trainLabelsTwo = getNewData(
                    train_data, train_labels, bestFeature, tree.range, 1)
                build(tree.left, trainDataOne,
                      trainLabelsOne, 0, forestfeatures)
                build(tree.right, trainDataTwo,
                      trainLabelsTwo, 1, forestfeatures)

def solve(tree, test_data_row):  # test_data row
    if tree.getIsLeaf() == False:
        transformed = test_data_row  # temp seeing if don't need to transform
        #transformed = transformMatrix(test_data_row,tree.feature)
        if transformed[tree.feature] <= tree.get_range():
            #print("transformed[tree.feature]",transformed[tree.feature],"original val",test_data_row[tree.feature],"divideval",tree.get_range())
            return solve(tree.left, test_data_row)
        else:
            #print("when feature > range transformed[tree.feature]",transformed[tree.feature],"original val",test_data_row[tree.feature],tree.get_range())
            return solve(tree.right, test_data_row)
    else:  # it is leaf so return val
        return tree.leafVal

def print_tree(tree):
    if tree.isLeaf:
        print(tree.leafVal, "->leaf.")
    else:
        print(tree.feature, "->tree feature.")
        print_tree(tree.left)
        print_tree(tree.right)

def compareRandomForests(treeArr, trainData, trainLabels):
    '''
    get accuracy of each random forest and return tree with best accuracy
    '''
    accuracyFinal = 0
    treeFinal = None
    for tree in treeArr:
        prediction = []
        for row in trainData:
            prediction.append(solve(tree, row))
        accuracy = len([i for i in range(
            len(prediction)) if prediction[i] == trainLabels[i]]) / float(len(prediction))
        if accuracy > accuracyFinal:
            accuracyFinal = accuracy
            treeFinal = tree
    #print("highest accuracy",accuracyFinal, "with",treeFinal)
    return treeFinal

def run_train_test(training_data, training_labels, testing_data):
    """
    Implement the training and testing procedure here. You are permitted
    to use additional functions but DO NOT change this function definition.

    Inputs:
        training_data: List[List[float]]
        training_label: List[int]
        testing_data: List[List[float]]

    Output:
        testing_prediction: List[int]
    Example:
    return [1]*len(testing_data)
    implement the decision tree and return the prediction
    """
    trainData = np.array(training_data)
    trainLabels = np.array(training_labels)
    testData = np.array(testing_data)

    #root = decisionTree()
    forestFeatures = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
    # build(root, trainData, trainLabels,2, forestFeatures) #original tree to test against
    # treeArr=[root]
    treeArr = []
    #trainMatrix = np.insert(trainData,19,trainLabels,1)
    for _ in range(8):
        #trainSample = trainMatrix[np.random.choice(trainMatrix.shape[0], 100, replace=False)]
        random.shuffle(forestFeatures) #For random forests, shuffling all features so it's built with 5 random features
        anotherRoot = decisionTree()
        build(anotherRoot, trainData, trainLabels, 2, forestFeatures[0:5])
        treeArr.append(anotherRoot)
    finalTree = compareRandomForests(treeArr, trainData, trainLabels)
    # print_tree(root)
    sol = []
    for row in testData:
        sol.append(solve(finalTree, row))
    return sol


pcts = ("10", "12", "15") # Tuple
pcts_types = " or ".join(pcts)

print("Welcome to the tip calculator!")
bill = float(input("What was the total bill? $"))
tip = int(input(f"What percentage tip would you like to give? {pcts_types}? "))
people = int(input(f"How many people to split the bill? "))
amount = round(((bill * tip) / 100 + bill) / people, 2)
amount = "{:.2f}".format(amount)
print(f"Each person should pay: ${amount}")


import numpy as np
import torch
import random
from PIL import Image

#---------------------------------------------------------#
#   将图像转换成RGB图像，防止灰度图在预测时报错。
#   代码仅仅支持RGB图像的预测，所有其它类型的图像都会转化成RGB
#---------------------------------------------------------#
def cvtColor(image):
    if len(np.shape(image)) == 3 and np.shape(image)[2] == 3:
        return image
    else:
        image = image.convert('RGB')
        return image

#---------------------------------------------------#
#   对输入图像进行resize
#---------------------------------------------------#
def resize_image(image, size, letterbox_image):
    iw, ih  = image.size
    w, h    = size
    if letterbox_image:
        scale   = min(w/iw, h/ih)
        nw      = int(iw*scale)
        nh      = int(ih*scale)

        image   = image.resize((nw,nh), Image.BICUBIC)
        new_image = Image.new('RGB', size, (128,128,128))
        new_image.paste(image, ((w-nw)//2, (h-nh)//2))
    else:
        new_image = image.resize((w, h), Image.BICUBIC)
    return new_image

def get_num_classes(annotation_path):
    with open(annotation_path) as f:
        dataset_path = f.readlines()

    labels = []
    for path in dataset_path:
        path_split = path.split(";")
        labels.append(int(path_split[0]))
    num_classes = np.max(labels) + 1
    return num_classes

#---------------------------------------------------#
#   获得学习率
#---------------------------------------------------#
def get_lr(optimizer):
    for param_group in optimizer.param_groups:
        return param_group['lr']

def preprocess_input(image):
    image /= 255.0
    return image

def show_config(**kwargs):
    print('Configurations:')
    print('-' * 70)
    print('|%25s | %40s|' % ('keys', 'values'))
    print('-' * 70)
    for key, value in kwargs.items():
        print('|%25s | %40s|' % (str(key), str(value)))
    print('-' * 70)

def random_crop(image, crop_shape, padding=None):
    oshape = np.shape(image)

    if padding:
        oshape = (oshape[2] + 2 * padding, oshape[3] + 2 * padding)
        npad = ((0, 0), (0, 0), (padding, padding), (padding, padding))

        image_pad = np.lib.pad(image, pad_width=npad, mode='constant', constant_values=0)
        nh = random.randint(0, oshape[0] - crop_shape[0])
        nw = random.randint(0, oshape[1] - crop_shape[1])
        image_crop = image_pad[:, :, nh:nh + crop_shape[0], nw:nw + crop_shape[1]]

        return image_crop
    else:
        print("WARNING!!! nothing to do!!!")
        return image

def load_pretrained_model(net, resume_net):
    print('Loading resume network...')
    state_dict = torch.load(resume_net)
    # create new OrderedDict that does not contain `module.`
    from collections import OrderedDict
    new_state_dict = OrderedDict()
    for k, v in state_dict.items():
        head = k[:7]
        if head == 'module.':
            name = k[7:]  # remove `module.`
        else:
            name = k
        new_state_dict[name] = v
    net.load_state_dict(new_state_dict)

def load_pretrained_model_Filter(net, state_dict):
    from collections import OrderedDict
    new_state_dict = OrderedDict()
    for k, v in state_dict.items():
        head = k[:7]
        if head == 'module.':
            name = k[7:]  # remove `module.`
        else:
            name = k
        new_state_dict[name] = v
    net.load_state_dict(new_state_dict)


import argparse
import json
from typing import List

from google.protobuf import json_format
from load_tests.common import (
    benchmark_grpc_request,
    make_full_request_type,
    make_output_file_path,
)
from magma.common.service_registry import ServiceRegistry
from orc8r.protos.common_pb2 import Void
from orc8r.protos.directoryd_pb2 import (
    DeleteRecordRequest,
    DirectoryRecord,
    GetDirectoryFieldRequest,
    UpdateRecordRequest,
)
from orc8r.protos.directoryd_pb2_grpc import GatewayDirectoryServiceStub

DIRECTORYD_SERVICE_NAME = 'directoryd'
DIRECTORYD_SERVICE_RPC_PATH = 'magma.orc8r.GatewayDirectoryService'
DIRECTORYD_PORT = '127.0.0.1:50067'
PROTO_PATH = 'orc8r/protos/directoryd.proto'

def _load_subs(num_subs: int) -> List[DirectoryRecord]:
    """Load directory records"""
    client = GatewayDirectoryServiceStub(
        ServiceRegistry.get_rpc_channel(
            DIRECTORYD_SERVICE_NAME, ServiceRegistry.LOCAL,
        ),
    )
    sids = []
    for i in range(num_subs):
        mac_addr = (str(i) * 2 + ":") * 5 + (str(i) * 2)
        ipv4_addr = str(i) * 3 + "." + str(i) * 3 + "." + str(i) * 3 + "." + str(i) * 3
        fields = {"mac-addr": mac_addr, "ipv4_addr": ipv4_addr}
        sid = UpdateRecordRequest(
            fields=fields,
            id=str(i).zfill(15),
            location=str(i).zfill(15),
        )
        client.UpdateRecord(sid)
        sids.append(sid)
    return sids

def _cleanup_subs():
    """Clear directory records"""
    client = GatewayDirectoryServiceStub(
        ServiceRegistry.get_rpc_channel(
            DIRECTORYD_SERVICE_NAME, ServiceRegistry.LOCAL,
        ),
    )
    for record in client.GetAllDirectoryRecords(Void()).records:
        sid = DeleteRecordRequest(
            id=record.id,
        )
        client.DeleteRecord(sid)

def _build_update_records_data(num_requests: int, input_file: str):
    update_record_reqs = []
    for i in range(num_requests):
        id = str(i).zfill(15)
        location = str(i).zfill(15)
        request = UpdateRecordRequest(
            id=id,
            location=location,
        )
        request_dict = json_format.MessageToDict(request)
        update_record_reqs.append(request_dict)
    with open(input_file, 'w') as file:
        json.dump(update_record_reqs, file, separators=(',', ':'))

def _build_delete_records_data(record_list: list, input_file: str):
    delete_record_reqs = []
    for index, record in enumerate(record_list):
        request = DeleteRecordRequest(
            id=record.id,
        )
        request_dict = json_format.MessageToDict(request)
        delete_record_reqs.append(request_dict)
    with open(input_file, 'w') as file:
        json.dump(delete_record_reqs, file, separators=(',', ':'))

def _build_get_record_data(record_list: list, input_file: str):
    get_record_reqs = []
    for index, record in enumerate(record_list):
        request = GetDirectoryFieldRequest(
            id=record.id,
            field_key="mac-addr",
        )
        request_dict = json_format.MessageToDict(request)
        get_record_reqs.append(request_dict)
    with open(input_file, 'w') as file:
        json.dump(get_record_reqs, file, separators=(',', ':'))

def _build_get_all_record_data(record_list: list, input_file: str):
    request = Void()
    get_all_record_reqs = json_format.MessageToDict(request)
    with open(input_file, 'w') as file:
        json.dump(get_all_record_reqs, file, separators=(',', ':'))

def update_record_test(args):
    input_file = 'update_record.json'
    _build_update_records_data(args.num_of_requests, input_file)
    request_type = 'UpdateRecord'
    benchmark_grpc_request(
        proto_path=PROTO_PATH,
        full_request_type=make_full_request_type(
            DIRECTORYD_SERVICE_RPC_PATH, request_type,
        ),
        input_file=input_file,
        output_file=make_output_file_path(request_type),
        num_reqs=args.num_of_requests, address=DIRECTORYD_PORT,
        import_path=args.import_path,
    )
    _cleanup_subs()

def delete_record_test(args):
    input_file = 'delete_record.json'
    record_list = _load_subs(args.num_of_requests)
    _build_delete_records_data(record_list, input_file)

    request_type = 'DeleteRecord'
    benchmark_grpc_request(
        proto_path=PROTO_PATH,
        full_request_type=make_full_request_type(
            DIRECTORYD_SERVICE_RPC_PATH, request_type,
        ),
        input_file=input_file,
        output_file=make_output_file_path(request_type),
        num_reqs=args.num_of_requests, address=DIRECTORYD_PORT,
        import_path=args.import_path,
    )
    _cleanup_subs()

def get_record_test(args):
    input_file = 'get_record.json'
    record_list = _load_subs(args.num_of_requests)
    _build_get_record_data(record_list, input_file)
    request_type = 'GetDirectoryField'
    benchmark_grpc_request(
        proto_path=PROTO_PATH,
        full_request_type=make_full_request_type(
            DIRECTORYD_SERVICE_RPC_PATH, request_type,
        ),
        input_file=input_file,
        output_file=make_output_file_path(request_type),
        num_reqs=args.num_of_requests, address=DIRECTORYD_PORT,
        import_path=args.import_path,
    )
    _cleanup_subs()

def get_all_records_test(args):
    input_file = 'get_all_records.json'
    record_list = _load_subs(args.num_of_requests)
    _build_get_all_record_data(record_list, input_file)
    request_type = 'GetAllDirectoryRecords'
    benchmark_grpc_request(
        proto_path=PROTO_PATH,
        full_request_type=make_full_request_type(
            DIRECTORYD_SERVICE_RPC_PATH, request_type,
        ),
        input_file=input_file,
        output_file=make_output_file_path(request_type),
        num_reqs=2000, address=DIRECTORYD_PORT,
        import_path=args.import_path,
    )
    _cleanup_subs()

def create_parser():
    """
    Creates the argparse subparser for all args
    """
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    )
    subparsers = parser.add_subparsers(title='subcommands', dest='cmd')

    parser_update_record = subparsers.add_parser(
        'update_record', help='Update record in directory',
    )

    parser_delete_record = subparsers.add_parser(
        'delete_record', help='Delete record in directory',
    )

    parser_get_record = subparsers.add_parser(
        'get_record', help='Get specific record in directory',
    )

    parser_get_all_records = subparsers.add_parser(
        'get_all_records', help='Get all records in directory',
    )

    for subcmd in [
        parser_update_record,
        parser_delete_record,
        parser_get_record,
        parser_get_all_records,
    ]:

        subcmd.add_argument(
            '--num_of_requests', help='Number of total records in directory',
            type=int, default=2000,
        )
        subcmd.add_argument(
            '--import_path', default=None, help='Protobuf import path directory',
        )

    parser_update_record.set_defaults(func=update_record_test)
    parser_delete_record.set_defaults(func=delete_record_test)
    parser_get_record.set_defaults(func=get_record_test)
    parser_get_all_records.set_defaults(func=get_all_records_test)

    return parser

def main():
    parser = create_parser()

    # Parse the args
    args = parser.parse_args()
    if not args.cmd:
        parser.print_usage()
        exit(1)

    # Execute the subcommand function
    args.func(args)

if __name__ == "__main__":
    main()


from flask_socketio import send, emit, join_room
from flaskapp.blueprints.web.models.chat import ChatModel

def getChat(socketio):
    # @socketio.on('connect')
    # def connect():
    #     print('connect: ')

    @socketio.on('joinPrivateGroup')
    def joinPrivateGroup(data):
        print('joinPrivateGroup', data)

        cm = ChatModel()
        prGr = cm.joinPrivateGroup(**data)
        join_room(prGr['id'])
        emit('joinPrivateGroup', prGr, json=True, room=prGr['id'])

    @socketio.on('messagePrivate')
    def messagePrivate(data):
        cm = ChatModel()
        msg = cm.messagePrivate(**data)
        if (not msg is None):
            emit('messagePrivate', msg, json=True, room=msg['chatId'])

    @socketio.on_error()
    def error_handler(e):
        print('@socketio.on_error', e)
        emit('error', {'error': str(e)}, json=True)


import pandas as pd
import numpy as np
import geopandas as gpd
from helper_functions import add_subset_address_cols, interpolate_polygon
from data_constants import default_crs, make_data_dict
from name_parsing import combine_names
from address_parsing import clean_parse_address
from helper_functions import make_panel
from pathos.multiprocessing import ProcessingPool as Pool
import re
import fiona

import warnings
warnings.filterwarnings("ignore", 'This pattern has match groups')

# function for reading in corrupted gdb files. really only relevant for LA CAMS data
def readShp_nrow(path, numRows):
    fiona_obj = fiona.open(str(path))
    toReturn = gpd.GeoDataFrame.from_features(fiona_obj[0:numRows])
    toReturn.crs = fiona_obj.crs
    return (toReturn)

# classify & clean name columns+ clean & parse primary and mailing addresses
# function that runs code in parallel
def parallelize_dataframe(df:pd.DataFrame, func, n_cores=4) -> pd.DataFrame:
    df_split = np.array_split(df, n_cores)
    pool = Pool(n_cores)
    df = pd.concat(pool.map(func, df_split))
    pool.close()
    pool.join()
    # have to include this to prevent leakage and allow multiple parallel function calls
    pool.terminate()
    pool.restart()
    return df

# wrapper function to run each city in parallel
def clean_parse_parallel(df:pd.DataFrame) -> pd.DataFrame:
    df = clean_parse_address(
        dataframe=df, address_col='address_fa',st_name="address_sn", st_sfx="address_ss",
        st_d="address_sd", unit='address_u', st_num='address_n1',
        country='address_country', state='address_state', st_num2 ='address_n2',city='address_city',
        zipcode='address_zip', prefix2='parsed_', prefix1='cleaned_'
    )
    return df

# ADDRESS CLEANING FUNCTIONS #
# takes an address df (geopandas or pandas), stanardizes and cleans it and returns a standardized pandas dataframe
# these functions get address dataframes to be in standardized formats (renamed columns, added variables, etc)
# such that the dataframe can be passed to clean_parse_parallel and exported
# see address cols in data constants for full list of necessary columns needed for clean_parse_parallel
# ill note if there is anything special with the function, but otherwise assume that it follows a standard flow of
# 1. rename columns -> add columns -> subset to only needed columns -> clean_parse_parrallel -> return

# chicago cleaning functions:
# chicago address files come in two seperate files that together represent a full set of addresses in cook county

# clean chi_add_points cleans a points file that represents centroid points for cook county parcel polygons
def clean_chi_add_points(df):
    chicago_rename_dict = {
        'ADDRNOCOM': 'address_n1',
        'STNAMEPRD': 'address_sd',
        'STNAME': 'address_sn',
        'STNAMEPOT': 'address_ss',
        'PLACENAME': 'address_city',
        'ZIP5': 'address_zip',
        'CMPADDABRV': 'address_fa',
        'PIN': 'parcelID',
        'XPOSITION': 'long',
        'YPOSITION': 'lat'
    }
    df.rename(columns=chicago_rename_dict, inplace=True)
    df = add_subset_address_cols(df)
    df = parallelize_dataframe(df=df, func=clean_parse_parallel, n_cores=2)
    return df

# basically the same as address points, but these are for parcel polygons (lat long are centroid points, so it is
# basically equivalent, these just have some addresses not in the other df and vice versa
def clean_chi_add_parcels(df):
    chicago_rename_dict = {
        'property_address':'address_fa',
        'property_city': 'address_city',
        'property_zip': 'address_zip',
        'pin': 'parcelID',
        'latitude': 'lat',
        'longitude': 'long'
    }
    df.rename(columns=chicago_rename_dict, inplace=True)
    df = add_subset_address_cols(df)
    df = parallelize_dataframe(df=df, func=clean_parse_parallel, n_cores=4)
    return df

def concat_chi_add(df1, df2):
    df1 = df1.append(df2).drop_duplicates(subset = [
        'parcelID',
        "parsed_addr_n1",
        "parsed_addr_sn",
        "parsed_addr_ss",
        "parsed_city"

    ])
    return df1

# saint louis is a little strange because they provide parcel polygons for entire streets
# eg main st 100-900. This is fine for small streets as its not problematic to take centroid polygons, but
# it becomes an issue for larger streets. For larger streets I take a best guess on which way the street runs and
# linearly interpolate lat long between the bottom and top range of the address span
# so if main st 100-900 runs nw that means it has its smallest numbers in the south east and increases going north west

def clean_stl_add(df):
    df = df.rename(
        columns = {
             "STREETNAME": "address_sn", "STREETTYPE": "address_ss", "PREDIR": "address_sd", "ZIP_CODE": "address_zip"
        }
    )
    df['index'] = np.arange(df.shape[0])
    df = df.to_crs(default_crs)
    df.crs = default_crs
    bounds = df.bounds
    df['address_city'] = 'saint louis'
    df['latitude_min'] = bounds["miny"]
    df['latitude_max'] = bounds["maxy"]
    df['longitude_min'] = bounds["minx"]
    df['longitude_max'] = bounds["maxx"]
    df['direction'] = np.where(
        ((df['FROMLEFT'] < df['TOLEFT']) & (df['FROMRIGHT'] < df['TORIGHT'])),
        "NE",
        np.where(
            ((df['FROMLEFT'] < df['TOLEFT']) & (df['FROMRIGHT'] > df['TORIGHT'])),
            "NW",
            np.where(
                ((df['FROMLEFT'] > df['TOLEFT']) & (df['FROMRIGHT'] < df['TORIGHT'])),
                "SE",
                np.where(
                    ((df['FROMLEFT'] > df['TOLEFT']) & (df['FROMRIGHT'] > df['TORIGHT'])),
                    "SW",
                    "SW"

                )
            )
        )
    )
    df_r = df[[col for col in df.columns if not bool(re.search("LEFT", col))]]
    df_r['address_n1'] = np.where(
        df_r['FROMRIGHT'] > df_r['TORIGHT'],
        df_r['TORIGHT'],
        df_r['FROMRIGHT']
    )
    df_r['address_n2'] = np.where(
        df_r['TORIGHT'] > df_r['FROMRIGHT'],
        df_r['TORIGHT'],
        df_r['FROMRIGHT']
    )
    df_l = df[[col for col in df.columns if not bool(re.search("RIGHT", col))]]
    df_l['address_n1'] = np.where(
        df_l['FROMLEFT'] > df_l['TOLEFT'],
        df_l['TOLEFT'],
        df_l['FROMLEFT']
    )
    df_l['address_n2'] = np.where(
        df_l['TOLEFT'] > df_l['FROMLEFT'],
        df_l['TOLEFT'],
        df_l['FROMLEFT']
    )
    df = pd.concat([df_r, df_l])
    df = df[~((df['address_n1'] <= 0) & (df['address_n1'] <= 0))]
    df = make_panel(df,start_year="address_n1", end_year="address_n2", current_year=df['address_n2'],
                    evens_and_odds=True ).rename(columns = {'year': 'address_n1'})
    # interpolate lat long

    df = interpolate_polygon(df, "index", "direction")
    df['lat'] = df['lat_interpolated']
    df['long'] = df["long_interpolated"]

    df = add_subset_address_cols(df)
    df = parallelize_dataframe(df=df, func=clean_parse_parallel, n_cores=2)
    return df

def clean_la_add(df):
    la_rename_dict = {
        'AIN': 'parcelID',
        'UnitName': 'address_u',
        'Number': 'address_n1',
        'PostType': 'address_ss',
        'PreDirAbbr':   'address_sd',
        'ZipCode': 'address_zip',
        'LegalComm': 'address_city',
    }
    df.rename(columns=la_rename_dict, inplace=True)
    combine_names(df, name_cols=['PreType', 'StArticle', 'StreetName'], newCol="address_sn")
    df = df.to_crs(default_crs)
    df.crs = default_crs
    df['long'] = df.geometry.centroid.x
    df['lat'] = df.geometry.centroid.y
    df = add_subset_address_cols(df)
    df = parallelize_dataframe(df=df, func=clean_parse_parallel, n_cores=2)
    return df

def clean_sd_add(df):
    sd_rename_dict = {
        'addrunit': 'address_u',
        'addrnmbr': 'address_n1',
        'addrpdir':'address_sd',
        'addrname': 'address_sn',
        'addrsfx': 'address_ss',
        'addrzip': 'address_zip',
        'community': 'address_city',
        'PIN': 'parcelID',
    }
    df.rename(columns=sd_rename_dict, inplace=True)
    df = df.to_crs(default_crs)
    df.crs = default_crs
    df['long'] = df.geometry.centroid.x
    df['lat'] = df.geometry.centroid.y
    df = add_subset_address_cols(df)
    df = parallelize_dataframe(df=df, func=clean_parse_parallel, n_cores=2)
    return df

def clean_sf_add(df):
    sf_rename_dict = {
        "Parcel Number": 'parcelID',
        'Unit Number': 'address_u',
        'Address Number': 'address_n1',
        'Street Name': 'address_sn',
        'Street Type':   'address_ss',
        'ZIP Code': 'address_zip',
        'Address': 'address_fa',
        #'PIN': 'parcelID',
        'Longitude': 'long',
        'Latitude': 'lat'
    }
    df.rename(columns=sf_rename_dict, inplace=True)
    df['address_city'] = "San Francisco"
    df = add_subset_address_cols(df)
    df = parallelize_dataframe(df=df, func=clean_parse_parallel, n_cores=2)
    return df

def clean_seattle_add(df):
    seattle_rename_dict = {
        'PIN': 'parcelID',
        'ADDR_NUM': 'address_n1',
        'ADDR_SN': 'address_sn',
        'ADDR_ST': 'address_ss',
        'ADDR_SD':   'address_sd',
        'ZIP5': 'address_zip',
        'CTYNAME': 'address_city',
        'ADDR_FULL': 'address_fa',
        'LON': 'long',
        'LAT': 'lat'
    }
    df.rename(columns=seattle_rename_dict, inplace=True)
    df = add_subset_address_cols(df)
    df = parallelize_dataframe(df=df, func=clean_parse_parallel, n_cores=2)
    return df

def clean_orlando_add(df):
    orlando_rename_dict = {
        'OFFICIAL_P': 'parcelID',
       "COMPLETE_A": 'address_fa',
        "ADDRESS__1": 'address_n1',
        "ADDRESS__2": "address_n2",
        "BASENAME": "address_sn",
        "POST_TYPE":"address_ss",
        "POST_DIREC":   "address_sd",
        "MUNICIPAL_": 'address_city',
        "ZIPCODE": "address_zip",
        "LATITUDE": "lat",
        "LONGITUDE": "long",
    }
    df.rename(columns=orlando_rename_dict, inplace=True)
    df = add_subset_address_cols(df)
    df = parallelize_dataframe(df=df, func=clean_parse_parallel, n_cores=2)
    return df

def clean_baton_rouge_add(df):
    baton_rouge_rename_dict = {
        'ADDRNOCOM': 'address_n1',
        'ASTREET PREFIX DIRECTION': 'address_sd',
        'STREET NAME': 'address_sn',
        'STREET SUFFIX TYPE': 'address_ss',
        'CITY': 'address_city',
        'ZIP': 'address_zip',
        'FULL ADDRESS': 'address_fa'
    }
    df.rename(columns=baton_rouge_rename_dict, inplace=True)
    lat_long = df['GEOLOCATION'].str.extract('([0-9\.]+),([0-9\.]+)')
    df['lat'] = lat_long.iloc[:,0]
    df['long'] = lat_long.iloc[:,1]
    df = add_subset_address_cols(df)
    df = parallelize_dataframe(df=df, func=clean_parse_parallel, n_cores=4)
    return df

def merge_sac_parcel_id(sac_add = pd.DataFrame,  xwalk = pd.DataFrame):
    return pd.merge(
        sac_add,
        xwalk[xwalk['Parcel_Number'].notna()][["Address_ID", "Parcel_Number"]].drop_duplicates(),
        left_on = "Address_ID", right_on = "Address_ID", how = "left"
        )

def clean_sac_add(df):
    sac_rename_dict = {
        'APN': 'parcelID',
        "Address_Number": 'address_n1',
        "Street_Name": "address_sn",
        "Street_Suffix":"address_ss",
        "Pre_Directiona;":   "address_sd",
        "Postal_City": 'address_city',
        "Zip_Code": "address_zip",
        "Latitude_Y": "lat",
        "Longitude_X": "long",
    }
    df.rename(columns=sac_rename_dict, inplace=True)
    df = add_subset_address_cols(df)
    df = parallelize_dataframe(df=df, func=clean_parse_parallel, n_cores=2)
    return df

# used to reclean data in the event that you dont want to read in a shapefile
# mostly uses because its faster to read in a csv than a shp
def clean_int_addresses(df):
    df = add_subset_address_cols(df)
    df = parallelize_dataframe(df=df, func=clean_parse_parallel, n_cores=2)
    return df

if __name__ == "__main__":
    print("hello")
    data_dict = make_data_dict(use_seagate=False)
    # stl_add = gpd.read_file(data_dict['raw']['stl']['parcel'] + 'streets/tgr_str_cl.shp')
    # stl_add = clean_stl_add(stl_add)
    # stl_add.to_csv(data_dict['intermediate']['stl']['parcel'] + 'addresses.csv', index=False)
    # baton_rouge_add = pd.read_csv(
    #     data_dict['raw']['baton_rouge']['parcel'] + 'addresses_Property_Information_ebrp.csv')
    # baton_rouge_add = clean_baton_rouge_add(baton_rouge_add)
    # baton_rouge_add.to_csv(data_dict['intermediate']['baton_rouge']['parcel'] + 'addresses.csv', index=False)
    # chicago_add1 = pd.read_csv(data_dict['raw']['chicago']['parcel'] + 'Cook_County_Assessor_s_Property_Locations.csv')
    # chicago_add2 = pd.read_csv(data_dict['raw']['chicago']['parcel'] + 'Address_Points_cook_county.csv')

    # orlando_add = gpd.read_file(data_dict['raw']['orlando']['parcel'] + "Address Points/ADDRESS_POINT.shp")
    # clean_orlando_add(orlando_add).to_csv(data_dict['intermediate']['orlando']['parcel'] + 'addresses.csv', index=False)

    # la_add = gpd.read_file("/Users/JoeFish/Desktop/la_addresspoints.gdb", nrows = 100)
    # la_add = pd.read_csv(data_dict['intermediate']['la']['parcel'] + 'addresses.csv')
    # file is corrupted so we have to read it in this way...
    # print(la_add.head())
    #sd_add = gpd.read_file(data_dict['raw']['sd']['parcel'] + 'addrapn_datasd_san_diego/addrapn_datasd.shp')
    # sf_add = pd.read_csv(
    #     data_dict['raw']['sf']['parcel'] + 'Addresses_with_Units_-_Enterprise_Addressing_System_san_francisco.csv')
    # seattle_add = gpd.read_file(data_dict['raw']['seattle']['parcel'] +
    #                           'Addresses_in_King_County___address_point/Addresses_in_King_County___address_point.shp')
    #
    # # clean_baton_rouge_add(baton_rouge_add).to_csv(data_dict['intermediate']['baton_rouge']['parcel'] + 'addresses.csv', index=False)
    # clean_chi_add2(chicago_add1).to_csv(data_dict['intermediate']['chicago']['parcel'] + 'addresses_from_parcels.csv', index=False)
    # clean_chi_add1(chicago_add2).to_csv(data_dict['intermediate']['chicago']['parcel'] + 'addresses_from_points.csv', index=False)
    # clean_int_addresses(la_add).to_csv(data_dict['intermediate']['la']['parcel'] + 'addresses_temp.csv', index=False)
    # clean_sf_add(sf_add).to_csv(data_dict['intermediate']['sf']['parcel'] + 'addresses.csv', index=False)
    # #clean_sd_add(sd_add).to_csv(data_dict['intermediate']['sd']['parcel'] + 'addresses.csv', index=False)
    # clean_seattle_add(seattle_add).to_csv(data_dict['intermediate']['seattle']['parcel'] + 'addresses.csv', index=False)
    # chi1 = pd.read_csv(data_dict['intermediate']['chicago']['parcel'] + 'addresses_from_parcels.csv', dtype={"parsed_addr_n1": str})
    # chi2 = pd.read_csv(data_dict['intermediate']['chicago']['parcel'] + 'addresses_from_points.csv', dtype={"parsed_addr_n1": str})
    # concat_chi_add(chi1,chi2).to_csv(data_dict['intermediate']['chicago']['parcel'] + 'addresses_concat.csv', index=False)
    sac_add = pd.read_csv(data_dict['raw']['sac']['parcel'] + 'Address.csv')
    sac_xwalk = pd.read_csv(data_dict['raw']['sac']['parcel'] + 'Address_parcel_xwalk.csv')
    sac_add = merge_sac_parcel_id(sac_add=sac_add, xwalk=sac_xwalk)
    clean_sac_add(sac_add).to_csv(data_dict['intermediate']['sac']['parcel'] + 'addresses_concat.csv', index=False)

    pass


from sre_constants import MAX_REPEAT
from .constants import MAX_STACK_DEPTH, MAX_UINT256

class Stack:
    def __init__(self, max_depth=MAX_STACK_DEPTH) -> None:
        self.stack = []
        self.max_depth = max_depth

    def push(self, item: int) -> None:
        if item < 0 or item > MAX_UINT256:
            raise InvalidStackItem({"item": item})

        if (len(self.stack) + 1) > self.max_depth:
            raise StackOverflow()

        self.stack.append(item)

    def pop(self) -> int:
        if len(self.stack) == 0:
            raise StackUnderflow()

        return self.stack.pop()

    def peek(self, i) -> int:
        """returns a stack element without popping it -- peek(0) is the top element, peek(1) is the next one, etc."""
        if len(self.stack) <= i:
            raise StackUnderflow()

        return self.stack[-(i + 1)]

    def swap(self, i: int) -> None:
        """swaps the top of the stack with the i+1th element"""
        if i == 0:
            return

        if len(self.stack) < i:
            raise StackUnderflow()

        self.stack[-1], self.stack[-i - 1] = self.stack[-i - 1], self.stack[-1]

    def __str__(self) -> str:
        return str(self.stack)

    def __repr__(self) -> str:
        return str(self)

class StackUnderflow(Exception):
    ...

class StackOverflow(Exception):
    ...

class InvalidStackItem(Exception):
    ...


from setuptools import setup, find_packages
import codecs
import os
import re

here = os.path.abspath(os.path.dirname(__file__))

import prefetch_generator
# loading README
long_description = prefetch_generator.__doc__

version_string = '1.0.2'

setup(
    name="prefetch_generator",
    version=version_string,
    description="a simple tool to compute arbitrary generator in a background thread",
    long_description=long_description,

    # Author details
    author_email="justheuristic@gmail.com",
    url="https://github.com/justheuristic/prefetch_generator",

    # Choose your license
    license='The Unlicense',
    packages=find_packages(),

    classifiers=[
        # Indicate who your project is intended for
        'Development Status :: 5 - Production/Stable',
        'Intended Audience :: Science/Research',
        'Intended Audience :: Developers',
        'Topic :: Scientific/Engineering',

        # Pick your license as you wish (should match "license" above)
        'License :: OSI Approved :: The Unlicense (Unlicense)',

        # Specify the Python versions you support here. In particular, ensure
        # that you indicate whether you support Python 2, Python 3 or both.
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
        'Programming Language :: Python :: 3.7',
        'Programming Language :: Python :: 3.8',
        'Programming Language :: Python :: 3.9',
        'Programming Language :: Python :: 3.10',

    ],

    # What does your project relate to?
    keywords='background generator, prefetch generator, parallel generator, prefetch, background,' + \
             'deep learning, theano, tensorflow, lasagne, blocks',

    # List run-time dependencies here. These will be installed by pip when your project is installed.
    install_requires=[
        #nothing
    ],
)


# Tip Calculator
# print welcome to the tip calculator
#what was the total bill ?
#what percentage tip would you like to a give ? 10,12,15
#how many people to split the bill ?
#each pearson should pay

print("##Welcome to the tip calculator##")
bill = float(input("what is total bill amount:"))
tip = int(input("what percenatge tip would you like to a give , 10 , 12 or 15 ?"))
people = int(input("how many people split the bill ?"))
bill_with_tip = tip/100*bill+bill
print(bill_with_tip)
total = bill_with_tip/people
print("each pearosn payable amount is:\n",total)


def voto(ano):
    from datetime import datetime
    atual = datetime.now().year
    idade = atual - ano
    if 16 <= idade <= 17 or idade > 60:
        return idade, 'VOTO OPCIONAL!'
    elif 18 <= idade < 60:
        return idade, 'VOTO OBRIGATÓRIO!'
    else:
        return idade, 'NÃO VOTA!'

nas = int(input('Em que ano voce nasceu? '))
print(f'Com {voto(nas)[0]} anos: {voto(nas)[1]}')


from __future__ import absolute_import
import math
from collections import OrderedDict

import torch
import torchvision
from torch import nn
from torch.nn import functional as F
import torch.utils.model_zoo as model_zoo

from .res2net import res2net50_26w_4s

__all__ = ['ResNet', 'resnet18', 'resnet34', 'resnet50', 'resnet101', 'resnet152',
           'TempoAvgPooling', 'TempoWeightedSum', 'TempoRNN']

model_urls = {
    'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',
    'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',
    'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',
    'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth',
    'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth',
}

def conv3x3(in_planes, out_planes, stride=1):
    "3x3 convolution with padding"
    return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,
                     padding=1, bias=False)

class TempoAvgPooling(nn.Module):
    """ Temporal Average Pooling """

    def __init__(self, num_classes):
        super(TempoAvgPooling, self).__init__()
        # resnet50 = torchvision.models.resnet50(pretrained=True)
        resnet50 = res2net50_26w_4s(pretrained=True)
        self.backbone = nn.Sequential(*list(resnet50.children())[:-2])
        self.last_layer_ch = 2048
        self.classifier = nn.Linear(self.last_layer_ch, num_classes, bias=False)
        nn.init.normal_(self.classifier.weight, std=0.01)

    def forward(self, x):
        """
        Args:
            x: (b t 3 H W)
        """
        b, t = x.size(0), x.size(1)
        x = x.view(b * t, x.size(2), x.size(3), x.size(4))
        x = self.backbone(x)  # (b*t c h w)
        x = F.avg_pool2d(x, x.size()[2:])
        x = x.view(b, t, -1).permute(0, 2, 1)  # (b t c) to (b c t)
        feature = F.avg_pool1d(x, t)  # (b c 1)
        feature = feature.view(b, self.last_layer_ch)

        if not self.training:
            return feature

        logits = self.classifier(feature)

        return logits, feature

class TempoWeightedSum(nn.Module):
    def __init__(self, num_classes):
        super(TempoWeightedSum, self).__init__()
        resnet50 = torchvision.models.resnet50(pretrained=True)
        self.backbone = nn.Sequential(*list(resnet50.children())[:-2])
        self.att_gen = 'softmax'  # method for attention generation: softMax or sigmoid
        self.last_layer_ch = 2048  # feature dimension
        self.middle_dim = 256  # middle layer dimension
        self.classifier = nn.Linear(self.last_layer_ch, num_classes, bias=False)
        nn.init.normal_(self.classifier.weight, std=0.01)

        # (7,4) corresponds to (224, 112) input image size
        self.spatial_attn = nn.Conv2d(self.last_layer_ch, self.middle_dim, kernel_size=[7, 4])
        self.temporal_attn = nn.Conv1d(self.middle_dim, 1, kernel_size=3, padding=1)

    def forward(self, x):
        b, t = x.size(0), x.size(1)
        x = x.view(b * t, x.size(2), x.size(3), x.size(4))
        featmaps = self.backbone(x)  # (b*t c h w)
        attn = F.relu(self.spatial_attn(featmaps)).view(b, t, -1).permute(0, 2, 1)  # (b*t c 1 1) to (b t c) to (b c t)
        attn = F.relu(self.temporal_attn(attn)).view(b, t)  # (b 1 t) to (b t)

        if self.att_gen == 'softmax':
            attn = F.softmax(attn, dim=1)
        elif self.att_gen == 'sigmoid':
            attn = F.sigmoid(attn)
            attn = F.normalize(attn, p=1, dim=1)
        else:
            raise KeyError("Unsupported attention generation function: {}".format(self.att_gen))

        feature = F.avg_pool2d(featmaps, featmaps.size()[2:]).view(b, t, -1)  # (b*t c 1 1) to (b t c)
        att_x = feature * attn.unsqueeze(attn, dim=-1)  # (b t c)
        att_x = torch.sum(att_x, dim=1)

        feature = att_x.view(b, -1)  # (b c)

        if not self.training:
            return feature

        logits = self.classifier(feature)

        return logits, feature

class TempoRNN(nn.Module):
    def __init__(self, num_classes):
        super(TempoRNN, self).__init__()
        resnet50 = torchvision.models.resnet50(pretrained=True)
        self.base = nn.Sequential(*list(resnet50.children())[:-2])
        self.hidden_dim = 512
        self.feat_dim = 2048
        self.classifier = nn.Linear(self.hidden_dim, num_classes, bias=False)
        nn.init.normal_(self.classifier.weight, std=0.01)

        self.lstm = nn.LSTM(input_size=self.feat_dim, hidden_size=self.hidden_dim, num_layers=1, batch_first=True)

    def forward(self, x):
        b = x.size(0)
        t = x.size(1)
        x = x.view(b * t, x.size(2), x.size(3), x.size(4))
        x = self.base(x)
        x = F.avg_pool2d(x, x.size()[2:])
        x = x.view(b, t, -1)
        output, (h_n, c_n) = self.lstm(x)
        output = output.permute(0, 2, 1)
        f = F.avg_pool1d(output, t)
        f = f.view(b, self.hidden_dim)
        if not self.training:
            return f
        y = self.classifier(f)

        return y, f

class BasicBlock(nn.Module):
    expansion = 1

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(BasicBlock, self).__init__()
        self.conv1 = conv3x3(inplanes, planes, stride)
        self.bn1 = nn.BatchNorm2d(planes)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = conv3x3(planes, planes)
        self.bn2 = nn.BatchNorm2d(planes)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        residual = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)

        if self.downsample is not None:
            residual = self.downsample(x)

        out += residual
        out = self.relu(out)

        return out

class Bottleneck(nn.Module):
    expansion = 4

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(Bottleneck, self).__init__()
        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
        self.bn1 = nn.BatchNorm2d(planes)
        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,
                               padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(planes)
        self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)
        self.bn3 = nn.BatchNorm2d(planes * 4)
        self.relu = nn.ReLU(inplace=True)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        residual = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)
        out = self.relu(out)

        out = self.conv3(out)
        out = self.bn3(out)

        if self.downsample is not None:
            residual = self.downsample(x)

        out += residual
        out = self.relu(out)
        return out

class ResNet(nn.Module):
    def __init__(self, block, layers, conv1_ch=3, conv5_stride=1, num_classes=1000):
        self.inplanes = 64
        super(ResNet, self).__init__()
        self.conv1 = nn.Conv2d(conv1_ch, 64, kernel_size=7, stride=2, padding=3,
                               bias=False)
        self.bn1 = nn.BatchNorm2d(64)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        self.layer1 = self._make_layer(block, 64, layers[0])
        self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
        self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
        self.layer4 = self._make_layer(block, 512, layers[3], stride=conv5_stride)
        self.avgpool = nn.AvgPool2d(7, stride=1)
        self.fc = nn.Linear(512 * block.expansion, num_classes)

        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                m.weight.data.normal_(0, math.sqrt(2. / n))
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()

    def _make_layer(self, block, planes, blocks, stride=1):
        downsample = None
        if stride != 1 or self.inplanes != planes * block.expansion:
            downsample = nn.Sequential(
                nn.Conv2d(self.inplanes, planes * block.expansion,
                          kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(planes * block.expansion))

        layers = []
        layers.append(block(self.inplanes, planes, stride, downsample))
        self.inplanes = planes * block.expansion
        for i in range(1, blocks):
            layers.append(block(self.inplanes, planes))

        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)

        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)

        x = self.avgpool(x)
        x = x.view(x.size(0), -1)
        x = self.fc(x)

        return x

def resnet18(pretrained=False, **kwargs):
    """Constructs a ResNet-18 model.

    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
    """
    model = ResNet(BasicBlock, [2, 2, 2, 2], **kwargs)
    if pretrained:
        model.load_state_dict(model_zoo.load_url(model_urls['resnet18']))
    return model

def resnet34(pretrained=False, **kwargs):
    """Constructs a ResNet-34 model.

    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
    """
    model = ResNet(BasicBlock, [3, 4, 6, 3], **kwargs)
    if pretrained:
        model.load_state_dict(model_zoo.load_url(model_urls['resnet34']))
    return model

def resnet50(pretrained=False, **kwargs):
    """Constructs a ResNet-50 model.

    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
    """
    model = ResNet(Bottleneck, [3, 4, 6, 3], **kwargs)
    if pretrained:
        model.load_state_dict(model_zoo.load_url(model_urls['resnet50']))
    return model

def resnet101(pretrained=False, **kwargs):
    """Constructs a ResNet-101 model.

    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
    """
    model = ResNet(Bottleneck, [3, 4, 23, 3], **kwargs)
    if pretrained:
        model.load_state_dict(model_zoo.load_url(model_urls['resnet101']))
    return model

def resnet152(pretrained=False, **kwargs):
    """Constructs a ResNet-152 model.

    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
    """
    model = ResNet(Bottleneck, [3, 8, 36, 3], **kwargs)
    if pretrained:
        model.load_state_dict(model_zoo.load_url(model_urls['resnet152']))
    return model

if __name__ == '__main__':
    model = resnet50()
    print(model)
    for block in model.layer2:
        print(block)


#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

# $Id: setup.py 30 2005-10-30 07:24:38Z oli $

import os, sys
from setuptools import setup, find_packages

sys.path.insert(0, 'package/lib')
from scapy import VERSION

PACKAGE_NAME = 'scapy'

DESCRIPTION="""Packet manipulation tool, packet generator, network scanner, packet sniffer, and much more."""
LONG_DESCRIPTION="""Powerful interactive packet... manipulation tool, packet generator, \
network... scanner, network discovery tool, and packet... sniffer."""

def find_data_files():
    files = [
             ('/usr/local/share/doc/scapy/', ['package/doc/LICENSE']),
             ('/usr/local/share/doc/scapy/', ['package/doc/ChangeLog']),
             ('/usr/local/share/doc/scapy/', ['package/doc/TODO']),
             ('/usr/local/bin/', ['package/usr/bin/iscapy'])
            ]
    if os.path.exists('package/doc/scapy.info.gz'):
        files.append( ('/usr/local/info/', ['package/doc/scapy.info.gz']) )
    if os.path.exists('package/doc/scapy.1.gz'):
        files.append( ('/usr/local/man/man1', ['package/doc/scapy.1.gz']) )
    return files

setup(name=PACKAGE_NAME,
      version=VERSION,
      license = """GNU General Public License (GPL)""",
      platforms = ['POSIX'],
      description = DESCRIPTION,
      long_description = LONG_DESCRIPTION,
      url = "http://www.secdev.org/projects/scapy/",
      download_url = "http://www.secdev.org/projects/scapy/files/scapy.py",
      author = "Philippe Biondi",
      author_email = "phil@secdev.org",
      classifiers = ["""Development Status :: 4 - Beta""",
                     """Environment :: Console""",
                     """Intended Audience :: Developers""",
                     """Intended Audience :: Education""",
                     """Intended Audience :: End Users/Desktop""",
                     """Intended Audience :: Information Technology""",
                     """Intended Audience :: Other Audience""",
                     """Intended Audience :: Science/Research""",
                     """Intended Audience :: System Administrators""",
                     """License :: OSI Approved :: GNU General Public License (GPL)""",
                     """Natural Language :: English""",
                     """Operating System :: POSIX""",
                     """Programming Language :: Python""",
                     """Topic :: Education :: Testing""",
                     """Topic :: Internet""",
                     """Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator""",
                     """Topic :: Security""",
                     """Topic :: Software Development :: Libraries :: Python Modules""",
                     """Topic :: Software Development :: Testing""",
                     """Topic :: Software Development :: Testing :: Traffic Generation""",
                     """Topic :: System""",
                     """Topic :: System :: Networking""",
                     """Topic :: System :: Networking :: Firewalls""",
                     """Topic :: System :: Networking :: Monitoring"""],
      package_dir = {'':'package/lib'},
      py_modules = ['scapy'],
      zip_safe=True,
      data_files = find_data_files()
      )


from uuid import uuid4

from demo.data_loading.data_fetching import get_countries_data
from demo.data_loading.fixes import fix_alpha2_value, fix_alpha3_value, fix_string_value
from demo.server.config import get_pyorient_client

def load_countries_and_regions(countries_df):
    graph = get_pyorient_client()

    country_cls = graph.registry['Country']
    region_cls = graph.registry['Region']
    subarea_cls = graph.registry['GeographicArea_SubArea']

    area_name_and_type_to_vertex = dict()

    # Create all countries.
    for _, country_item in countries_df.iterrows():
        name = fix_string_value(country_item['CLDR display name'])
        uuid = str(uuid4())
        alpha2 = fix_alpha2_value(country_item['ISO3166-1-Alpha-2'])
        alpha3 = fix_alpha3_value(country_item['ISO3166-1-Alpha-3'])

        props = {
            'name': name,
            'uuid': uuid,
            'alpha2': alpha2,
            'alpha3': alpha3,
        }
        vertex = graph.create_vertex(country_cls, **props)
        area_name_and_type_to_vertex[(name, 'Country')] = vertex

    # Create all non-country regions.
    for _, country_item in countries_df.iterrows():
        for region_column in ('Intermediate Region Name', 'Sub-region Name', 'Region Name'):
            name = fix_string_value(country_item[region_column])
            if name is None or (name, 'Region') in area_name_and_type_to_vertex:
                # Don't create regions with no name, or regions that were already added.
                continue

            uuid = str(uuid4())

            props = {
                'name': name,
                'uuid': uuid,
            }
            vertex = graph.create_vertex(region_cls, **props)
            area_name_and_type_to_vertex[(name, 'Region')] = vertex

    # Create all relationships between countries/regions.
    created_edges = set()
    for _, country_item in countries_df.iterrows():
        hierarchy_order = (
            ('CLDR display name', 'Country'),
            ('Intermediate Region Name', 'Region'),
            ('Sub-region Name', 'Region'),
            ('Region Name', 'Region'),
        )
        regions_in_order = [
            (region_name, kind)
            for region_name, kind in (
                (fix_string_value(country_item[column_name]), kind)
                for column_name, kind in hierarchy_order
            )
            if region_name is not None
        ]

        for index, (parent_region_name, parent_region_kind) in enumerate(regions_in_order):
            if index == 0:
                continue

            child_region_name, child_region_kind = regions_in_order[index - 1]

            uniqueness_key = (
                parent_region_name,
                parent_region_kind,
                child_region_name,
                child_region_kind,
            )
            if uniqueness_key not in created_edges:
                graph.create_edge(
                    subarea_cls,
                    area_name_and_type_to_vertex[(parent_region_name, parent_region_kind)],
                    area_name_and_type_to_vertex[(child_region_name, child_region_kind)])
                created_edges.add(uniqueness_key)

    # Link all currently parent-less regions to the World region.
    all_region_names = set(area_name_and_type_to_vertex.keys())
    all_regions_with_parents = {
        (child_region_name, child_region_kind)
        for _, _, child_region_name, child_region_kind in created_edges
    }
    all_regions_without_parents = all_region_names - all_regions_with_parents

    world_vertex = graph.create_vertex(region_cls, name='World', uuid=str(uuid4()))
    for region_name, region_kind in all_regions_without_parents:
        graph.create_edge(
            subarea_cls,
            world_vertex,
            area_name_and_type_to_vertex[(region_name, region_kind)])

def orientdb_load_all():
    countries_df = get_countries_data()
    load_countries_and_regions(countries_df)

if __name__ == '__main__':
    orientdb_load_all()


import os
import string
import Model.Gobject
import Model.Global
import Model.Exceptions

import gettext
t = Model.Global.getTrans()
if t != None:
    _= t.gettext
else:
    def _(x):
        return x

def createTable(dataBase):
    db= Database.DbAccess.DbAccess(dataBase)
    db.createTable(VatList._tableName, Vat._varsType)
    db.close()

class Vat(Model.Gobject.Gobject):
    """Vat variables from database table:

    'id:' The Vat's unique database table index, int

    'vatCode:' A numeric identifier used somewhere, 1 char

    'vatName:' Name of this variant, ≤15 char

    'vatRate:' The rate in percent, ≤10 char (int or float)

    'vatAccount:' The account number to post the VAT of this variant,
    4 char

    'salesAccount:' For sale variants: The account number where the net amount
    shall be posted, 4 char.
    """
    _varsType= (('id','INDEX.0'),
                ('vatCode','BCHAR.1'),
                ('vatName','BCHAR.15'),
                ('vatRate','BCHAR.10'),
                ('vatAccount','BCHAR.4'),
                ('salesAccount', 'BCHAR.4'))

    _vars= ()
    for i in _varsType:
        _vars= _vars+ (i[0],)
    # Generate the format, a number of '%s:%s:%s:...'
    _fmt= ("%s:"*len(_vars))[:-1]
    # Generate the expression, '(self._var1, self._var2,...)'
    _tuple=(('('+'self._%s,'*len(_vars))[:-1] + ')'
                 )%_vars
    # compiled expressions
    _cToTuple= compile(_tuple, '<string>', 'eval')
    _cToObject= compile(_tuple+'= t','<string>', 'exec')

    def __init__(self, t= None):
        Model.Gobject.Gobject.__init__(self, t)

    def copyOfVat(self):
        t= self.objectToDbTuple()
        return Vat(t)

    def __cmp__(self, o2):
        return  cmp(self._vatCode, o2._vatCode)

    # property actions
    def getVatCode(self):
        return self._vatCode
    def setVatCode(self, vc):
        self._vatCode= vc
    vatCode= property(getVatCode, setVatCode, None, None)

    def getVatName(self):
        return self._vatName
    def setVatName(self, vc):
        self._vatName= vc
    vatName= property(getVatName, setVatName, None, None)

    def getVatRate(self):
        return self._vatRate
    def setVatRate(self, vc):
        self._vatRate= vc
    vatRate= property(getVatRate, setVatRate, None, None)

    def getVatAccount(self):
        return self._vatAccount
    def setVatAccount(self, vc):
        self._vatAccount= vc
    vatAccount= property(getVatAccount, setVatAccount, None, None)

    def getSalesAccount(self):
        return self._salesAccount
    def setSalesAccount(self, vc):
        self._salesAccount= vc
    salesAccount= property(getSalesAccount, setSalesAccount, None, None)

    def getId(self):
        return self._id
    def setId(self, dummy):
        self._id= None
    id= property(getId, setId, None, None)

### VatList ###

class VatList(Model.Gobject.GList):
    _tableName= 'vat'
    _objectName= None
    def __init__(self, database=None):
        self._objectName= 'Vat'
        self._vars= Vat._vars
        self._init= Vat
        self._database= database
        if database != None:
            self._connection= Database.DbAccess.DbAccess(database)
        else:
            self._connection= None
        Model.Gobject.GList.__init__(self, self._connection)

    def fixup(self, lists):
        self.sort()

    def getByCode(self, code):
        """
        Return the object with vatCode == code

        'code:' vatCode, 1 digit char
        'return:' The found object, None if not found
        """
        for e in self:
            if e._vatCode == code: return e
        return None

    #For some reason the Vat-objects are only referenced to by the vatCode
    # id is only used to follow the Gobject template and to make a distinction
    # between saved and new objects

    def __repr__(self):
        return 'VatList'

def _readFile(f):
    vatL= []
    all= f.readlines()
    for a in all:
        li= string.strip(a)
        if len(li) < 3 or li[0] == '#' : continue
        fields= string.split(a, ':') # raises ValueError
        if len(a) < 10: continue
        vr= Vat()
        try:
            #raises IndexError if not 5 fields
            vr.vatCode= string.strip(fields[0])
            vr.vatName= string.strip(fields[1])
            vr.vatRate= string.strip(fields[2])
            vr.vatAccount= string.strip(fields[3])
            vr.salesAccount= string.strip(fields[4])
        except IndexError:
            raise(Model.Exceptions.FileError(_(
                "Missing field in file of default VAT")))
        vatL.append(vr)
    return vatL

def readFile(fn):
    try:
        f= open(fn, 'r')
        vL= _readFile(f)
        f.close()
        vatL= Model.Books.getList('vat')
        for v in vL:
            vatL.saveEntry(v)

    except IOError:
        raise(Model.Exceptions.FileError(_("Could not read file ") + fn))

    except ValueError:
        raise(Model.Exceptions.FileError(_("Syntax error in file ") + fn))


# Дана последовательность чисел. Определить наибольшую длину монотонно возрастающего фрагмента
# последовательности (то есть такого фрагмента, где все элементы больше предыдущего).

n = int(input('Введите количество чисел '))
m = float(input('Введите первое число '))

prev = m
lenght = 1
max_lenght = 0

for k in range(2, n + 1):
    m = float(input('Введите очередное число '))
    if m > prev:
        lenght = lenght + 1
    # Кончился какой-то монотонно возрастающий фрагмент последовательности.Сравниваем его длину с максимальной длиной
    else:
        if lenght > max_lenght:
            max_lenght = lenght
        # Начинается "новый" фрагмент
        lenght = 1
    # Введенное число станет предыдущим для следующего числа
    prev = m
# Проверяем длину последнего монотонно возрастающего фрагмента последовательности
if lenght > max_lenght:
    max_lenght = lenght

print(max_lenght)


"""
GenT2_Rulebase.py
Created 9/1/2022
"""
from juzzyPython.generalType2zSlices.system.GenT2Engine_Intersection import GenT2Engine_Intersection
from juzzyPython.generalType2zSlices.system.GenT2Engine_Union import GenT2Engine_Union
from juzzyPython.generalType2zSlices.system.GenT2_Rule import GenT2_Rule
from juzzyPython.intervalType2.system.IT2_Rulebase import IT2_Rulebase
from juzzyPython.generalType2zSlices.system.GenT2_Antecedent import GenT2_Antecedent

from typing import List, OrderedDict

from juzzyPython.testing.timeRecorder import timeDecorator
class GenT2_Rulebase():
    """
    Class GenT2_Rulebase
    Keeps track of rules and generates results

    Parameters:
        None

    Functions:
        addRule
        addRules
        getRules
        getFuzzyLogicType
        get_GenT2zEngine_Intersection
        get_GenT2zEngineUnion
        getOverallOutput
        evaluateGetCentroid
        evaluate
        getIT2Rulebases
        getRule
        changeRule
        removeRule
        getNumberOfRules
        containsRule
        getRulesWithAntecedents
        getImplicationMethod
        setImplicationMethod
        toString

    """

    def __init__(self) -> None:
        self.rules = []
        self.outputs = []
        self.DEBUG = False
        self.CENTEROFSETS = 0
        self.CENTROID = 1
        self.implicationMethod = 1
        self.PRODUCT = 0
        self.MINIMUM = 1
        self.gzEU = GenT2Engine_Union()
        self.gzEI = GenT2Engine_Intersection()

    def addRule(self,r: GenT2_Rule) -> None:
        """Add a new rule to the rule set"""
        self.rules.append(r)
        it = r.getConsequents()
        for i in it:
            o = i.getOutput()
            if not o in self.outputs:
                self.outputs.append(o)

    def addRules(self,r: List[GenT2_Rule]) -> None:
        """Add multiple new rules to the rule set"""
        for i in range(len(r)):
            self.addRule(i)

    def getRules(self) -> List[GenT2_Rule]:
        """Return all the rules in the set"""
        return self.rules

    def getRule(self,ruleNum: int) -> GenT2_Rule:
        """Return a specific rule"""
        return self.rules[ruleNum]

    def getNumberOfRules(self) -> int:
        """Get the number of rules in the set"""
        return len(self.rules)

    def getFuzzyLogicType(self) -> int:
        """Returns the type of fuzzy logic that is employed.
        return 0: type-1, 1: interval type-2, 2: zSlices based general type-2"""
        return 2

    def containsRule(self,rule: GenT2_Rule) -> bool:
        """Check if a rule in the ruleset"""
        return rule in self.rules

    def getGenT2zEngineIntersection(self) -> GenT2Engine_Intersection:
        """Return the intersection engine"""
        return self.gzEI

    def getGenT2zEngineUnion(self) -> GenT2Engine_Union:
        """Return the union engine"""
        return self.gzEU

    def removeRule(self,ruleNumber: int) -> None:
        """Remove a rule based on its index"""
        del self.rules[ruleNumber]

    def getImplicationMethod(self) -> str:
        """Return if the implication is product or minimum"""
        if self.implicationMethod == self.PRODUCT:
            return "product"
        else:
            return "minimum"

    def setImplicationMethod(self,implicationMethod: int) -> None:
        """Sets the implication method, where by implication, we mean the implementation
        of the AND logical connective between parts of the antecedent.
        The desired implication method is applied for all rules."""
        if implicationMethod == self.PRODUCT:
            self.implicationMethod = self.PRODUCT
        elif implicationMethod == self.MINIMUM:
            self.implicationMethod = self.MINIMUM
        else:
            raise Exception("Only product (0) and minimum (1) implication is currently supported.")

    def toString(self) -> str:
        """Convert the class to string"""
        s = "General Type-2 Fuzzy Logic System with "+str(self.getNumberOfRules())+" rules:\n"
        for i in range(self.getNumberOfRules()):
            s += str(self.rules[i].toString())+"\n"
        return s

    def getOverallOutput(self) -> dict:
        """Return the overall output of the rules"""
        returnValue = OrderedDict()
        for r in range(len(self.rules)):
            temp = self.rules[r].getRawOutput()
            for o in self.outputs:
                if r == 0:
                    returnValue[o] = temp[o]
                else:
                    returnValue[o] = self.gzEU.getUnion(returnValue.get(o),temp.get(o))
        return returnValue

    def evaluateGetCentroid(self,typeReductionType: int) -> dict:
        """Returns the output of the FLS after type-reduction, i.e. the centroid.
        param: typeReductionType
        return: A TreeMap where Output is used as key and the value is an Object[]
        where Object[0] is a Tuple[] (the centroids, one per zLevel) and Object[1] is a Double holding the associated yValues for the centroids. If not rule fired for the given input(s),
        then null is returned as an Object[]."""
        returnValue = OrderedDict()
        rbsIT2 = self.getIT2Rulebases()
        zValues = self.rules[0].getAntecedents()[0].getSet().getZValues()

        for i in range(len(rbsIT2)):
            temp = rbsIT2[i].evaluateGetCentroid(typeReductionType)
            for o in temp.keys():
                if i == 0:
                    returnValue[o] = [[],[]]
                returnValue[o][0].append(temp[o][0])
                returnValue[o][1].append(zValues[i])
        return returnValue

    def evaluate(self,typeReductionType: int) -> dict:
        """The current evaluate function is functional but inefficient. It creates an IT2
        version of all the rules in the rulebase and computes each IT2 rule separately...
        param typeReductionType: 0: Center Of Sets, 1: Centroid
        param discretizationLevel: The discretization level on the xAxis"""
        returnValue = OrderedDict()
        rbsIT2 = self.getIT2Rulebases()
        rawOutputValues = []

        for i in range(len(rbsIT2)):
            rawOutputValues.append(rbsIT2[i].evaluate(typeReductionType))
        zValues = self.rules[0].getAntecedents()[0].getSet().getZValues()

        for o in self.outputs:
            i=0
            numerator = 0.0
            denominator = 0.0

            for outputValue in rawOutputValues:
                numerator += outputValue[o] * zValues[i]
                denominator += zValues[i]
                i+= 1
            returnValue[o] = numerator/denominator
        return returnValue

    def getIT2Rulebases(self) -> List[IT2_Rulebase]:
        """Returns the whole zSlices based rulebase as a series of interval type-2
        rule bases (one per zLevel) which can then be computed in parallel.
        param typeReductionMethod: The type-reduction method to be used at the IT2 level
        0: Center Of Sets,  1: Centroid.
        param discretizationLevelXAxis: The number of discretizations to be used at the IT2 level."""
        rbs = [0] * self.rules[0].getAntecedents()[0].getSet().getNumberOfSlices()
        for i in range(len(rbs)):
            rbs[i] = IT2_Rulebase()
            for currentRule in range(self.getNumberOfRules()):
                rbs[i].addRule(self.rules[currentRule].getRuleasIT2Rules()[i])
            rbs[i].setImplicationMethod(self.implicationMethod)
        return rbs

    def getRulesWithAntecedents(self,antecedents: List[GenT2_Antecedent]) -> List[GenT2_Rule]:
        """ Returns all rules with a matching (i.e. equal) set of antecedents."""
        matches = []
        for i in range(len(self.rules)):
            if self.rules[i].getAntecedents()==antecedents:
                matches.append(self.rules[i])
        return matches


from decimal import Decimal
from fractions import Fraction
from typing import Generator

from numeric_methods.language import TRANSLATE
from numeric_methods.language.docs.one_variable import SECANT_METHOD_DOCS
from numeric_methods.mathematics import compare, convert, widest_type

NUMBER = Decimal | float | Fraction

@TRANSLATE.documentation(SECANT_METHOD_DOCS)
def secant_method(function, x_prev: NUMBER, x: NUMBER, epsilon: NUMBER) -> Generator[tuple[NUMBER] | NUMBER, None, None]:
    # Type normalization
    Number = widest_type(x_prev, x, epsilon)
    x_prev = convert(x_prev, Number)
    x = convert(x, Number)
    epsilon = convert(epsilon, Number)

    step = 1
    next_x = x - (x - x_prev) * function(x) / (function(x) - function(x_prev))
    yield step, next_x
    while not compare(abs(next_x - x), "<", epsilon):
        step += 1
        x_prev = x
        x = next_x
        next_x = x - (x - x_prev) * function(x) / (function(x) - function(x_prev))
        yield step, next_x
    yield next_x


from aws_cdk import (
    aws_ec2 as ec2,
    aws_ecs as ecs,
    cdk,
)

class GhostOnEcsStack(cdk.Stack):

    def __init__(self, scope: cdk.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, *kwargs)

        # Create VPC and Fargate Cluster
        # NOTE: Limit AZs to avoid reaching resource quotas
        vpc = ec2.VpcNetwork(
            self, "MyGhostOnEcsVpc",
            max_a_zs=2
        )

        cluster = ecs.Cluster(
            self, 'Ec2GhostOnEcsCluster',
            vpc=vpc
        )

        fargate_service = ecs.LoadBalancedFargateService(
            self, "FargateGhostOnEcsService",
            cluster=cluster,
            image=ecs.ContainerImage.from_registry("ghost")
        )

        cdk.CfnOutput(
            self, "LoadBalancerDNS",
            value=fargate_service.load_balancer.dns_name
        )


import os
from BadParser import BadParser

proxies = []

class ProxyWorker(object):
    def handler(path):
        if os.path.isfile(path=path) != True:
            return False
        if os.path.splitext(path)[1] != '.txt':
            return False
        f = open(path, 'r', encoding='utf-8')
        line = f.readline().replace('\\n', '')
        line = line.strip()
        while line:
            proxies.append(line)
            line = f.readline().replace('\\n', '')
            line = line.strip()
        f.close()
        return proxies

    def AutoGrabber(pages):
        print('\n')
        prox = BadParser(3, pages)
        data = prox.Grab()
        if ProxyWorker.FileCreating(data) is False:
            print('Can\'t save proxies.\n')
        return data

    def DirectoryChecker():
        try:
            if not os.path.exists('./proxies/'):
                os.mkdir('./proxies/')
                return True
        except:
            print('Can\'t save proxies.\n')
            return False

    def FileCreating(data):
        if ProxyWorker.DirectoryChecker() is False:
            return False
        f = open('./proxies/last_proxies.txt', 'w', encoding='utf-8')
        for i in data:
            f.write(i + '\n')
        f.close()


import random, os, shutil, yaml, gzip
import pandas as pd
import numpy as np
import prepare.configs as configs
from google.cloud import storage
import pickle
import time

storage_client = storage.Client()
bucket = storage_client.bucket(configs.bucketName)

def encodeConfigs(_confs):
    return [
        _confs['sim time settings']['time step'],
        _confs['sim time settings']['total time'],
        _confs['sim time settings']['sampling rate'],
        int(_confs['change Na mem']['event happens']),
        _confs['change Na mem']['change start'],
        _confs['change Na mem']['change finish'],
        _confs['change Na mem']['change rate'],
        _confs['change Na mem']['multiplier'],
        int(_confs['change K mem']['event happens']),
        _confs['change K mem']['change start'],
        _confs['change K mem']['change finish'],
        _confs['change K mem']['change rate'],
        _confs['change K mem']['multiplier']
    ]

def generateDataset():
    srcFolder = "storage/processed"
    destFolder = "storage/ready"
    inputMaxCellsNumber = 250
    retryCounter = 0

    # Fetch available simulation folders
    runsIdxs = []
    for blob in bucket.list_blobs(prefix=srcFolder):
        folderName = blob.name.split("/")
        if (folderName[2] not in runsIdxs and folderName[2] != ""):
            runsIdxs.append(folderName[2])

    # Ftech simulation folders already processed
    with open("./prepare/processed.txt","r") as f:
        processedRunsIdxs = f.readlines()
        processedRunsIdxs = [folder.strip() for folder in processedRunsIdxs]

    availableFolders = []
    for runIdx in runsIdxs:
        if (runIdx not in processedRunsIdxs):
            availableFolders.append(runIdx)

    print("[GENERATE DATASET] Folders {} | Processed {} | Left {}".format(len(runsIdxs), len(processedRunsIdxs), len(availableFolders)))
    for i, runFolderIdx in enumerate(availableFolders):
        # Keep track of the progress
        if (i in [int(len(availableFolders)*0.25), int(len(availableFolders)*0.5), int(len(availableFolders)*0.75)]):
            print(">> {} %".format(int(i / len(availableFolders) * 100)))

        try:
            data = pd.read_csv('gs://{}/{}/{}/simulation.csv'.format(configs.bucketName, srcFolder, runFolderIdx))
            print(">> {} | {}".format(runFolderIdx, data['folderName'][0]))

            # 1. Download Sim Config File and encode It
            fileDest = '/tmp/rawSimConfig.yml'
            bucket.blob('storage/raw/{}/configs.yml'.format(data['folderName'][0])).download_to_filename(fileDest)
            with open(fileDest, 'r') as stream:
                simConfigRaw = yaml.safe_load(stream)
            simConfigsEncoded = np.asarray(encodeConfigs(simConfigRaw))
            simConfigsEncoded = np.append(simConfigsEncoded, [0]) # Add timestamp information

            # 2. Download Sim.betse File and open it ( to extract Membrane permeabilities values)
            fileDest = '/tmp/sim_1.betse.gz'
            bucket.blob('storage/raw/{}/sim_1.betse.gz'.format(data['folderName'][0])).download_to_filename(fileDest)
            with gzip.open(fileDest, "rb") as f:
                sim, cells, params = pickle.load(f)

            # 3. Generate training examples files. One for each simulation timestep using sim config, sim.betse & vmems
            for timestampIdx in range(len(sim.time)):
                inputVmem = np.asarray(data[data['timestamp'] == timestampIdx]['vmem'])
                outputVmem = np.asarray(data[data['timestamp'] == timestampIdx + 1]['vmem'])

                # Update timestamp information
                simConfigsEncoded[simConfigsEncoded.shape[0] - 1] = timestampIdx

                # 1. Compute cells perms values from cells membranes perms values. From {3, 6} values to 1 (average)
                cellsPopulationSize = inputVmem.shape[0]
                cells_mems = [[] for cell in range(cellsPopulationSize)]
                for memUniqueIdx, cellIdx in enumerate(cells.mem_to_cells):
                    cells_mems[cellIdx].append(sim.dd_time[timestampIdx][:, memUniqueIdx])

                cells_permeabilities = []
                for cellMembranes in cells_mems:
                    cells_permeabilities.append(np.mean(cellMembranes, axis=0))
                cells_permeabilities = np.asarray(cells_permeabilities) # N, 4 # K, Na, M-, Proteins-

                # concat Vmem values with perms values
                inputVmem = np.concatenate((inputVmem.reshape((-1, 1)), cells_permeabilities), axis=1) # N, 5

                # concat cells centers to input vector
                inputVmem = np.concatenate((inputVmem, cells.cell_centres), axis=1) # N, 7

                # Concat env concentrations
                env_cc = np.transpose(sim.cc_env_time[timestampIdx])[ : inputVmem.shape[0]] # get only same shape as inputVmem since env cc all the same
                inputVmem = np.concatenate((inputVmem, env_cc), axis=1) # N, 11

                # Concat cytosilic concentrations
                cytosolic_cc = np.transpose(sim.cc_time[timestampIdx])
                inputVmem = np.concatenate((inputVmem, cytosolic_cc), axis=1) # N, 15

                #Pad Input
                '''
                TODO:
                - Not pad with 0 since it is a possible Vmem value.
                '''
                if (inputVmem.shape[0] < inputMaxCellsNumber):
                    inputVmemPad = np.zeros((inputMaxCellsNumber, inputVmem.shape[1]))
                    inputVmemPad[:inputVmem.shape[0]] = inputVmem
                    inputVmem = inputVmemPad

                    outputVmemPad = np.zeros((inputMaxCellsNumber))
                    outputVmemPad[:outputVmem.shape[0]] = outputVmem
                    outputVmem = outputVmemPad
                #Discard Input
                elif (inputVmem.shape[0] > inputMaxCellsNumber):
                    print("<<ATTENTION>> Found Input with Numbers of cells higher that current Max: {} > {}".format(inputVmem.shape[0], inputMaxCellsNumber))
                    continue

                # Discard example if data
                # - Vmem < - 100 || > 100
                # - K_env, Na_env, M_env, X_env, K_cc, Na_cc, M_cc, X_cc > 1000
                #

                if (np.any(inputVmem[:, 0] < -100) or np.any(inputVmem[:, 0] > 100)):
                    print("Discard example, Vmem {}".format(np.max(np.abs(inputVmem))))
                    continue

                if (np.any(inputVmem[: , 7:] > 1000)):
                    print("Discard example, Concentration {}".format(np.max(inputVmem[: , 7:])))
                    continue

                if (np.any(outputVmem[:, 0] < -100) or np.any(outputVmem[:, 0] > 100)):
                    print("Discard example, Vmem Output {}".format(np.max(np.abs(outputVmem))))
                    continue
                #print("inputVmem length: {}".format(inputVmem.shape[0]))
                #print("Configs length: {}".format(configs.shape[0]))
                #print("outputVmem length: {}".format(outputVmem.shape[0]))
                filePath = '/tmp/example.npy'
                np.save(filePath, np.asarray([
                    inputVmem,
                    simConfigsEncoded,
                    outputVmem
                ], dtype="object"))
                blob = bucket.blob('{}/{}/{}.npy'.format(destFolder, runFolderIdx, timestampIdx))
                blob.upload_from_filename(filePath)

            retryCounter = 0
            with open("./prepare/processed.txt","a+") as f:
                f.write(runFolderIdx + "\n")
        # If for some reason processing fails. Handle it. It will not save on the processed.txt allowing to be processed at the next restart
        except:
            print("Handle Excpetion | Sleeping for {}".format(2 ** retryCounter))
            time.sleep(2 ** retryCounter) # sleep since may be due to too many requests
            retryCounter += 1
            continue


import torch
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision.datasets import MNIST

from dae.dae import DAE
from beta_vae.beta_vae import BetaVAE
from history import History

# hyperparameters
num_epochs = 100
batch_size = 128
lr = 1e-4
beta = 4
save_iter = 20

shape = (28, 28)
n_obs = shape[0] * shape[1]

# create DAE and ß-VAE and their training history
dae = DAE(n_obs, num_epochs, batch_size, 1e-3, save_iter, shape)
beta_vae = BetaVAE(n_obs, num_epochs, batch_size, 1e-4, beta, save_iter, shape)
history = History()

# fill autoencoder training history with examples
print('Filling history...', end='', flush=True)

transformation = transforms.Compose([
    transforms.ColorJitter(),
    transforms.ToTensor()
])

dataset = MNIST('data', transform=transformation)
dataloader = DataLoader(dataset, batch_size=1, shuffle=True)

for data in dataloader:
    img, _ = data
    img = img.view(img.size(0), -1).numpy().tolist()
    history.store(img)
print('DONE')

# train DAE
dae.train(history)

# train ß-VAE
beta_vae.train(history, dae)