if __name__ == '__main__':
    from nnunetv2.paths import nnUNet_results, nnUNet_raw
    import torch
    from batchgenerators.utilities.file_and_folder_operations import join
    from nnunetv2.inference.predict_from_raw_data import nnUNetPredictor
    from nnunetv2.imageio.simpleitk_reader_writer import SimpleITKIO

    # nnUNetv2_predict -d 3 -f 0 -c 3d_lowres -i imagesTs -o imagesTs_predlowres --continue_prediction

    # instantiate the nnUNetPredictor
    predictor = nnUNetPredictor(
        tile_step_size=0.5,
        use_gaussian=True,
        use_mirroring=True,
        perform_everything_on_gpu=True,
        device=torch.device('cuda', 0),
        verbose=False,
        verbose_preprocessing=False,
        allow_tqdm=True
    )
    # initializes the network architecture, loads the checkpoint
    predictor.initialize_from_trained_model_folder(
        join(nnUNet_results, 'Dataset003_Liver/nnUNetTrainer__nnUNetPlans__3d_lowres'),
        use_folds=(0,),
        checkpoint_name='checkpoint_final.pth',
    )
    # variant 1: give input and output folders
    predictor.predict_from_files(join(nnUNet_raw, 'Dataset003_Liver/imagesTs'),
                                 join(nnUNet_raw, 'Dataset003_Liver/imagesTs_predlowres'),
                                 save_probabilities=False, overwrite=False,
                                 num_processes_preprocessing=2, num_processes_segmentation_export=2,
                                 folder_with_segs_from_prev_stage=None, num_parts=1, part_id=0)

    # variant 2, use list of files as inputs. Note how we use nested lists!!!
    indir = join(nnUNet_raw, 'Dataset003_Liver/imagesTs')
    outdir = join(nnUNet_raw, 'Dataset003_Liver/imagesTs_predlowres')
    predictor.predict_from_files([[join(indir, 'liver_152_0000.nii.gz')],
                                  [join(indir, 'liver_142_0000.nii.gz')]],
                                 [join(outdir, 'liver_152.nii.gz'),
                                  join(outdir, 'liver_142.nii.gz')],
                                 save_probabilities=False, overwrite=True,
                                 num_processes_preprocessing=2, num_processes_segmentation_export=2,
                                 folder_with_segs_from_prev_stage=None, num_parts=1, part_id=0)

    # variant 2.5, returns segmentations
    indir = join(nnUNet_raw, 'Dataset003_Liver/imagesTs')
    predicted_segmentations = predictor.predict_from_files([[join(indir, 'liver_152_0000.nii.gz')],
                                                            [join(indir, 'liver_142_0000.nii.gz')]],
                                                           None,
                                                           save_probabilities=True, overwrite=True,
                                                           num_processes_preprocessing=2,
                                                           num_processes_segmentation_export=2,
                                                           folder_with_segs_from_prev_stage=None, num_parts=1,
                                                           part_id=0)

    # predict several npy images
    from nnunetv2.imageio.simpleitk_reader_writer import SimpleITKIO

    img, props = SimpleITKIO().read_images([join(nnUNet_raw, 'Dataset003_Liver/imagesTs/liver_147_0000.nii.gz')])
    img2, props2 = SimpleITKIO().read_images([join(nnUNet_raw, 'Dataset003_Liver/imagesTs/liver_146_0000.nii.gz')])
    img3, props3 = SimpleITKIO().read_images([join(nnUNet_raw, 'Dataset003_Liver/imagesTs/liver_145_0000.nii.gz')])
    img4, props4 = SimpleITKIO().read_images([join(nnUNet_raw, 'Dataset003_Liver/imagesTs/liver_144_0000.nii.gz')])
    # we do not set output files so that the segmentations will be returned. You can of course also specify output
    # files instead (no return value on that case)
    ret = predictor.predict_from_list_of_npy_arrays([img, img2, img3, img4],
                                                    None,
                                                    [props, props2, props3, props4],
                                                    None, 2, save_probabilities=False,
                                                    num_processes_segmentation_export=2)

    # predict a single numpy array
    img, props = SimpleITKIO().read_images([join(nnUNet_raw, 'Dataset003_Liver/imagesTs/liver_147_0000.nii.gz')])
    ret = predictor.predict_single_npy_array(img, props, None, None, True)

    # custom iterator

    img, props = SimpleITKIO().read_images([join(nnUNet_raw, 'Dataset003_Liver/imagesTs/liver_147_0000.nii.gz')])
    img2, props2 = SimpleITKIO().read_images([join(nnUNet_raw, 'Dataset003_Liver/imagesTs/liver_146_0000.nii.gz')])
    img3, props3 = SimpleITKIO().read_images([join(nnUNet_raw, 'Dataset003_Liver/imagesTs/liver_145_0000.nii.gz')])
    img4, props4 = SimpleITKIO().read_images([join(nnUNet_raw, 'Dataset003_Liver/imagesTs/liver_144_0000.nii.gz')])

    # each element returned by data_iterator must be a dict with 'data', 'ofile' and 'data_properties' keys!
    # If 'ofile' is None, the result will be returned instead of written to a file
    # the iterator is responsible for performing the correct preprocessing!
    # note how the iterator here does not use multiprocessing -> preprocessing will be done in the main thread!
    # take a look at the default iterators for predict_from_files and predict_from_list_of_npy_arrays
    # (they both use predictor.predict_from_data_iterator) for inspiration!
    def my_iterator(list_of_input_arrs, list_of_input_props):
        preprocessor = predictor.configuration_manager.preprocessor_class(verbose=predictor.verbose)
        for a, p in zip(list_of_input_arrs, list_of_input_props):
            data, seg = preprocessor.run_case_npy(a,
                                                  None,
                                                  p,
                                                  predictor.plans_manager,
                                                  predictor.configuration_manager,
                                                  predictor.dataset_json)
            yield {'data': torch.from_numpy(data).contiguous().pin_memory(), 'data_properties': p, 'ofile': None}

    ret = predictor.predict_from_data_iterator(my_iterator([img, img2, img3, img4], [props, props2, props3, props4]),
                                               save_probabilities=False, num_processes_segmentation_export=3)


try:
    file1 = open('testi.txt', 'r')
    count = 0

    # Using for loop
    rivit = []
    for line in file1:
        rivit.append(line.strip('\n'))

    # Closing files
    rivit.sort()
    rivit.sort(key=len)
    print(rivit)
    file1.close()
except:
    print("An exception occurred")


#import sys;

class BankAccount:
    def __init__(self, accountNumber, name ):
        self.__accountNumber = accountNumber
        self.__name = name

    def get_account_number(self):
        return self.__accountNumber

    def get_name(self):
        return self.__name

    def set_account_number(self, value):
        self.__accountNumber = value

    def set_name(self, value):
        self.__name = value

class FixedDeposit(BankAccount):
    def __init__(self, accountNumber, name, duration, amount, rateOfInterest ):
        super().__init__(accountNumber,name)
        self.__duration = duration
        self.__amount = amount
        self.__rateOfInterest = rateOfInterest

    def get_duration(self):
        return self.__duration

    def get_amount(self):
        return self.__amount

    def get_rate_of_interest(self):
        return self.__rateOfInterest

    def set_duration(self, value):
        self.__duration = value

    def set_amount(self, value):
        self.__amount = value

    def set_rate_of_interest(self, value):
        self.__rateOfInterest = value

class RecurringDeposit(BankAccount):
    def __init__(self, accountNumber, name, duration, monthlyPayment, rateOfInterest ):
        super().__init__(accountNumber,name)
        self.__duration = duration
        self.__monthlyPayment = monthlyPayment
        self.__rateOfInterest = rateOfInterest

    def get_duration(self):
        return self.__duration

    def get_monthly_payment(self):
        return self.__monthlyPayment

    def get_rate_of_interest(self):
        return self.__rateOfInterest

    def set_duration(self, value):
        self.__duration = value

    def set_monthly_payment(self, value):
        self.__monthlyPayment = value

    def set_rate_of_interest(self, value):
        self.__rateOfInterest = value

class BankDemo:
    n=0
    ch='n'

    def bankOptions(self):
        print("******************************")
        print("  Banco Cuenta ")
        print("******************************")
        print("1. Depósito fijo de lectura y escritura")
        print("2. Depósito recurrente de lectura y escritura")
        print("3. salir")

        n=int(input("\nSeleccione su elección: "))
        if n==1:
            self.readWriteFixedDeposit()
        elif n==2:
            self.readWriteRecurringDeposit()
        elif n==3:
            print("¡¡¡Gracias!!!")
            exit()
        else:
            print("¡opción inválida! \ n inténtalo de nuevo \ n")
            self.bankOptions()

    def readWriteFixedDeposit(self):
        print("\ nDar detalles de depósito fijo \ n")
        j=0
        while(j==0):
            try:
                accountNumber = int(input("Ingrese el número de cuenta:").strip())
                j=1
            except:
                print("Inténtalo de nuevo")
        name =input("Ingrese el nombre de la cuenta:").strip()
        j=0
        while(j==0):
            try:
                duration = int(input("Duración:").strip())
                j=1
            except:
                print("Inténtalo de nuevo")
        j=0
        while(j==0):
            try:
                amount = float(input("Monto: ").strip())
                j=1
            except:
                print("Inténtalo de nuevo")

        j=0
        while(j==0):
            try:
                rateOfInterest = float(input("Tipo de interés:").strip())
                j=1
            except:
                print("Inténtalo de nuevo")

        fd = FixedDeposit(accountNumber, name, duration, amount, rateOfInterest)

        print("\n Los detalles del depósito fijo son ... \n")
        print("\n Número de cuenta: ", fd.get_account_number())
        print("Nombre de la cuenta:", fd.get_name())
        print("Duración:", fd.get_duration())
        print("Monto: ", fd.get_amount())
        print("Tipo de interés: ", fd.get_rate_of_interest())

    def readWriteRecurringDeposit(self):
        print("\n Dar detalles de depósitos recurrentes \n")
        j=0
        while(j==0):
            try:
                accountNumber = int(input("Ingrese el número de cuenta: ").strip())
                j=1
            except:
                print("Inténtalo de nuevo ")
        name =input("Ingrese el nombre de la cuenta: ").strip()
        j=0
        while(j==0):
            try:
                duration = int(input("Duración: ").strip())
                j=1
            except:
                print("Inténtalo de nuevo")
        j=0
        while(j==0):
            try:
                monthlyPayment = float(input("Mensualidad:").strip())
                j=1
            except:
                print("Inténtalo de nuevo")

        j=0
        while(j==0):
            try:
                rateOfInterest = float(input("Tasa de interés:").strip())
                j=1
            except:
                print("Inténtalo de nuevo")

        rd = RecurringDeposit(accountNumber, name, duration, monthlyPayment, rateOfInterest)

        print("\n Los detalles del depósito recurrente son ... \n")
        print("\nNúmero de cuenta: ", rd.get_account_number())
        print("Nombre de la cuenta: ", rd.get_name())
        print("Duración:", rd.get_duration())
        print("Mensualidad: ", rd.get_monthly_payment())
        print("Tipo de interés: ", rd.get_rate_of_interest())

    def gotooptions(self):
        if self.n!=3:
            ch=input("\n¿Desea continuar (s / n)?").strip()
            if(ch[0]=='y' or ch[0]=='Y'):
                BankDemo.bankOptions(self)
            else:
                print("¡Gracias!")
                exit()

demoObject = BankDemo()
demoObject.bankOptions()
demoObject.gotooptions()


# -*- coding: utf-8 -*-
"""
Created on Tue Apr 10 20:01:09 2018

@author: TNT
"""
import os

#classes
import zctaoverview as zo

import FileHelper as fh
import TypeHelper as th

def getOverviewForZCTA(zcta, overviewData):
    matching = [z for z in overviewData if z.ZCTA == zcta]

    if len(matching) > 0:
        return matching[0]

    return zo.ZCTAOverview('', zcta, '', 0.0)

#processing
def processOverviewData(fileList):
    data = []
    #rowCount = 0
    for line in fileList:
        #if rowCount > 0:

        lineZCTA = th.cleanInts(line['ZCTA'])
        staticData = list(filter(lambda s: s.ZCTA == lineZCTA, allZCTAWithNBH))
        if(len(staticData) > 0):
            sLine = staticData[0]
            #ov = zo.ZCTAOverview(line['boroLabel'], line['zcta'], line['nbhLabel'], line['PctChange'])
            ov = zo.ZCTAOverview(sLine.Boro, line['ZCTA'], sLine.Neighborhood, line['G.Index'])
            data.append(ov)
        #rowCount += 1

    return data

def processStaticFileData(fileList):
    data = []
    rowCount = 0
    for line in fileList:
        if rowCount > 0:
            cleanZip = th.cleanInts(line['zcta5'])
            if len(line['zcta5']) == 5 and cleanZip != 0 and cleanZip not in [z.ZCTA for z in data]:
                ov = zo.ZCTAOverview(line['boro'], line['zcta5'], line['neighborhoodlabel'], 0.0)
                data.append(ov)
        rowCount += 1

    return data

def mergeForMissingZCTA(indexData, zctaData):
    zctasWIndex = [i.ZCTA for i in indexData]
    missing = [z for z in zctaData if z.ZCTA not in zctasWIndex]
    return indexData + missing

#max and min
def GetMinGenIndex():
    minObj = min(GENOVERVIEWDATA, key=lambda z: z.GenIndex)
    if minObj is not None:
        return minObj.GenIndex

    return 0

def GetMaxGenIndex():
    maxObj = max(GENOVERVIEWDATA, key=lambda z: z.GenIndex)
    if maxObj is not None:
        return maxObj.GenIndex

    return 100

#run first
#get the main zcta file first, this isn't going to change
zctaStaticFile = os.getcwd() + "/mysite/Datafiles/zip_to_zcta10_nyc_with_NBH.csv"
allZCTAWithNBH = fh.readInCSVDicData(zctaStaticFile, processStaticFileData)

#then the index file, which needs the all zcta file to get the nbh and other data
zctaIndexFile = os.getcwd() + "/mysite/Datafiles/GIndexByZCTA.csv"
#data
genOverviewData = fh.readInCSVDicData(zctaIndexFile, processOverviewData)

GENOVERVIEWDATA = mergeForMissingZCTA(genOverviewData, allZCTAWithNBH) #load the data first so we have it


def main(input):

    def readfile(textfile):
        with open(file=f"{textfile}", mode="r") as f:
            return [line.replace('\n','') for line in f]

    def getPosition(input):
        directions = [x.split(' ') for x in readfile(input)]
        x = 0
        y = 0
        for i in directions:
            direction = i[0]
            distance = int(i[1])
            if direction == 'forward':
                x += distance
            elif direction == 'back':
                x -= distance
            elif direction == 'up':
                y -= distance
            elif direction == 'down':
                y += distance
        return x*y

    def getPositionWithAim(input):
        directions = [x.split(' ') for x in readfile(input)]
        x = 0
        y = 0
        aim = 0
        for i in directions:
            direction = i[0]
            command = int(i[1])
            if direction == 'forward':
                x += command
                y += (command*aim)
            elif direction == 'up':
               aim -= command
            elif direction == 'down':
                aim += command
        return x*y

    print(f"Problem 1 answer is: {getPosition(input)}")
    print(f"Problem 2 answer is: {getPositionWithAim(input)}")

if __name__ == "__main__":
    main('Day2\day2_input.txt')


""" Axis Aligned Bounding Boxes for coarse collision detection
"""
import numpy as np
from elastica.utils import MaxDimension

class AABBCollection:
    def __init__(
        self,
        elemental_position_collection,
        dimension_collection,
        elements_per_aabb: int,
    ):
        """
        Doesn't differentiate tangent direction from the rest : potentially harmful as
        maybe you don't need to expand to radius amount in tangential direction

        :param position_collection:
        :param dimension_collection:
        :param elements_per_aabb:
        """
        n_positions = elemental_position_collection.shape[1]  # n_pos
        self.n_aabb = n_positions // elements_per_aabb
        self.n_aabb += (
            1 if (n_positions % elements_per_aabb) else 0
        )  # extra if not perfectly divisible
        self.elements_per_aabb = elements_per_aabb
        self.aabb = np.empty(
            (MaxDimension.value(), 2, self.n_aabb)
        )  # 2 for min and max

        assert dimension_collection.shape[1] == n_positions, "bad"

        # Initialize the aabbs posthaste
        self.update(elemental_position_collection, dimension_collection)

    @classmethod
    def make_from_aabb(cls, aabb_collection, scale_factor=4):
        # Make position collection and dimension collection arrays from aabb_collection
        # Wasted effort, but only once during construction
        n_aabb_from_lower_level = len(aabb_collection)
        elemental_position_collection = np.zeros(
            (MaxDimension.value(), n_aabb_from_lower_level)
        )
        # (r,r,dl) in (d1,d2,d3) coordinates
        dimension_collection = np.zeros((MaxDimension.value(), n_aabb_from_lower_level))

        for idx, aabb in enumerate(aabb_collection):
            # By design in the bottom level, there's only one AABB. So the last index is always 1
            # Also asserting herre
            assert aabb.n_aabb == 1, "Number of aabbs not 1"
            elemental_position_collection[..., idx] = 0.5 * (
                aabb.aabb[..., 0, 0] + aabb.aabb[..., 1, 0]
            )
            dimension_collection[..., idx] = 0.5 * (
                aabb.aabb[..., 1, 0] - aabb.aabb[..., 0, 0]
            )

        return cls(elemental_position_collection, dimension_collection, scale_factor)

    def _update(self, aabb_collection):
        # Updates internal state from another aabb

        """
        for i in range(self.n_aabb):
            start = i * self.elements_per_aabb
            stop = (i + 1) * self.elements_per_aabb

            self.aabb[..., 0, i] = np.amin(aabb_collection[..., 0, start:stop], axis=1)
            self.aabb[..., 1, i] = np.amax(aabb_collection[..., 1, start:stop], axis=1)
        """

        # Guaranteed that self.n_aabb = 1 and start, stop corresponds to aabb_collection
        # so directly do it
        temp = np.array([aabb.aabb[..., 0, 0] for aabb in aabb_collection])
        self.aabb[..., 0, 0] = np.amin(temp, axis=0)
        temp = np.array([aabb.aabb[..., 1, 0] for aabb in aabb_collection])
        self.aabb[..., 1, 0] = np.amax(temp, axis=0)

    def update(self, elemental_position_collection, dimension_collection):
        # Initialize the boxes
        for i in range(self.n_aabb):
            start = i * self.elements_per_aabb
            stop = (i + 1) * self.elements_per_aabb
            self.aabb[..., 0, i] = np.amin(
                elemental_position_collection[..., start:stop], axis=1
            ) - np.amax(dimension_collection[..., start:stop], axis=1)
            self.aabb[..., 1, i] = np.amax(
                elemental_position_collection[..., start:stop], axis=1
            ) + np.amax(dimension_collection[..., start:stop], axis=1)

def find_nearest_integer_square_root(x: int):
    from math import sqrt

    return round(sqrt(x))

class AABBHierarchy:
    """Simple hierarchy for handling cylinder collisions alone, meant for a rod"""

    def __init__(
        self, position_collection, dimension_collection, avg_n_dofs_in_final_level
    ):
        """
        scaling is always set to 4, so that theres' 1 major AABBCollection, then scaling_factor
        smaller AABBs, then scaling factor even smaller AABBs (which cover the elements
        basically)
        :param position_collection:
        """
        # Determine empirical scaling factor based on how many dofs are available in the
        # system
        n_positions = position_collection.shape[1]
        assert dimension_collection.shape[1] == n_positions, "bad"

        # First determine the number of levels according to 1,4,16,64...
        potential_n_aabbs_in_final_level = n_positions // avg_n_dofs_in_final_level
        potential_n_aabbs_in_final_level += (
            1 if n_positions % avg_n_dofs_in_final_level else 0
        )

        # nearest power of 4 that is less than the number
        n_levels_bound_below = np.int(
            np.floor(0.5 * np.log2(potential_n_aabbs_in_final_level))
        )
        n_levels_bound_above = np.int(
            np.ceil(0.5 * np.log2(potential_n_aabbs_in_final_level))
        )
        # Check which is the closest and use that as the number of levels

        # Else check differences
        if (4 ** n_levels_bound_above - potential_n_aabbs_in_final_level) > (
            potential_n_aabbs_in_final_level - 4 ** n_levels_bound_below
        ):
            self.n_levels = n_levels_bound_below + 1
        else:
            # If they are the same, then its an exact power of four which is good
            # the same code works
            self.n_levels = n_levels_bound_above + 1

        n_aabbs_in_final_level = 4 ** (self.n_levels - 1)
        self.avg_n_dofs_in_final_level = n_positions // n_aabbs_in_final_level
        # Needs to be distributed across aabbs
        self.extra_n_dofs_in_final_level = n_positions % n_aabbs_in_final_level

        assert self.extra_n_dofs_in_final_level < n_aabbs_in_final_level

        # self.n_aabbs_in_first_level = find_nearest_integer_square_root(n_positions)
        # self.avg_n_dofs_in_second_level = n_positions // self.n_aabbs_in_first_level
        # self.extra_n_dofs_in_second_level = n_positions % self.n_aabbs_in_first_level

        # We now need to construct all AABBs in the hierarchy sequentially from bottom
        # up
        self.aabb = []

        # Bottom level, already updated
        # Need to slice position collections and dimension_collections
        # elements_per_aabb is 1 as we are going to have the finest discretization
        stop = 0
        for i in range(n_aabbs_in_final_level - self.extra_n_dofs_in_final_level):
            start = stop
            stop = (i + 1) * self.avg_n_dofs_in_final_level
            self.aabb.append(
                AABBCollection(
                    position_collection[..., start:stop],
                    dimension_collection[..., start:stop],
                    self.avg_n_dofs_in_final_level,
                )
            )

        # Slice with an extra element (+1) to accommodate extra dofs
        # Done extra_n_dofs times
        for i in range(
            n_aabbs_in_final_level - self.extra_n_dofs_in_final_level,
            n_aabbs_in_final_level,
        ):
            start = stop
            stop = start + (self.avg_n_dofs_in_final_level + 1)
            self.aabb.append(
                AABBCollection(
                    position_collection[..., start:stop],
                    dimension_collection[..., start:stop],
                    self.avg_n_dofs_in_final_level + 1,
                )
            )

        # Now for all levels above, add an AABB taking cues from the previously constructed AABBs
        # Depends on the current level, start from 0
        count_elapsed_n_aabbs = 0
        for level in range(self.n_levels - 1):
            # Traverse bottom down
            # If 0, traverse n_level - 1 hierarchy, 1 traverse n_level -2 hierarchy and so on...
            # if levle = self.n_levels - 2, correct_level is 0
            correct_level = self.n_levels - level - 2
            n_aabbs_in_current_level = 4 ** (correct_level)
            n_aabbs_in_next_level = 4 ** (correct_level + 1)
            for i_aabb in range(n_aabbs_in_current_level):
                # Get start, stop indices of n_aabbs from previous level
                start_idx_in_aabb_list = i_aabb * 4 + count_elapsed_n_aabbs
                stop_idx_in_aabb_list = (i_aabb + 1) * 4 + count_elapsed_n_aabbs
                # n_aabb from prev levels
                assert (
                    stop_idx_in_aabb_list
                    <= count_elapsed_n_aabbs + n_aabbs_in_next_level
                )
                self.aabb.append(
                    AABBCollection.make_from_aabb(
                        self.aabb[start_idx_in_aabb_list:stop_idx_in_aabb_list]
                    )
                )
            count_elapsed_n_aabbs += n_aabbs_in_next_level

        # Add one for the middle level
        # self.aabb.append(AABBCollection(position_collection, dimension_collection, self.n_aabbs_in_first_level))

    def n_aabbs_at_level(self, i: int):
        assert i < self.n_levels
        return 4 ** (i)

    def update(self, position_collection, dimension_collection):
        # Update bottom level first, the first level entries
        n_aabbs_in_final_level = self.n_aabbs_at_level(self.n_levels - 1)
        stop = 0
        for i in range(n_aabbs_in_final_level - self.extra_n_dofs_in_final_level):
            start = stop
            stop = (i + 1) * self.avg_n_dofs_in_final_level
            self.aabb[i].update(
                position_collection[..., start:stop],
                dimension_collection[..., start:stop],
            )

        # Slice with an extra element (+1) to accommodate extra dofs
        # Done extra_n_dofs times
        for i in range(
            n_aabbs_in_final_level - self.extra_n_dofs_in_final_level,
            n_aabbs_in_final_level,
        ):
            start = stop
            stop = start + (self.avg_n_dofs_in_final_level + 1)
            self.aabb[i].update(
                position_collection[..., start:stop],
                dimension_collection[..., start:stop],
            )

        # Update all other levels middle level from bottom level's aabbs
        count_elapsed_n_aabbs = 0
        for level in range(self.n_levels - 2, 0 - 1, -1):
            # Traverse bottom down
            # If 0, traverse n_level - 1 hierarchy, 1 traverse n_level -2 hierarchy and so on...
            # if levle = self.n_levels - 2, correct_level is 0
            n_aabbs_in_current_level = self.n_aabbs_at_level(level)
            n_aabbs_in_next_level = self.n_aabbs_at_level(level + 1)
            for i_aabb in range(n_aabbs_in_current_level):
                # Get start, stop indices of n_aabbs from previous level
                start_idx_in_aabb_list = i_aabb * 4 + count_elapsed_n_aabbs
                stop_idx_in_aabb_list = (i_aabb + 1) * 4 + count_elapsed_n_aabbs
                self.aabb[
                    count_elapsed_n_aabbs + n_aabbs_in_next_level + i_aabb
                ]._update(self.aabb[start_idx_in_aabb_list:stop_idx_in_aabb_list])
            count_elapsed_n_aabbs += n_aabbs_in_next_level

def are_aabb_intersecting(first_aabb_collection, second_aabb_collection):
    return True


import sqlite3

connection = sqlite3.connect("company.db")
cursor = connection.cursor()

list_employees = """
SELECT id, name, position
FROM company
"""

monthly = """
SELECT monthly_salary
FROM company
"""

yearly = """
SELECT monthly_salary, yearly_bonus
FROM company
"""

add_employee = """
INSERT INTO company
(name, monthly_salary, yearly_bonus, position)
VALUES(?, ?, ?, ?)
"""

get_name = """
SELECT name
FROM company
WHERE id = {}
"""

delete = """
DELETE FROM company
WHERE id = {}
"""

update = """
UPDATE company SET
name = ?,
monthly_salary = ?,
yearly_bonus = ?,
position = ?
WHERE id = ?
"""

def main():
    while True:
        c = input("command>")

        if c == "list_employees":
            result = cursor.execute(list_employees)
            for line in result:
                print("{} - {} - {}".format(line[0], line[1], line[2]))

        elif c == "monthly_spending":
            result = cursor.execute(monthly)
            spending = sum([salary[0] for salary in result])
            print("The company is spending ${} every month!".format(spending))

        elif c == "yearly_spending":

            result = cursor.execute(yearly)
            spending = sum([salary[0] for salary in result]) * 12

            result = cursor.execute(yearly)
            bonus = sum([salary[1] for salary in result])

            spending += bonus
            print("The company is spending ${} every year!".format(spending))

        elif c == "add_employee":

            empl_name = input("name>")
            empl_salary = input("monthly_salary>")
            empl_bonus = input("yearly_bonus>")
            empl_position = input("position>")

            cursor.execute(add_employee, (empl_name, empl_salary, empl_bonus, empl_position))
            connection.commit()

        elif "delete_employee" in c:
            empl_id = c[16:]
            empl_name = cursor.execute(get_name.format(empl_id))[0]
            cursor.execute(delete.format(empl_id))
            connection.commit()
            print("{} was deleted.".format(name))

        elif "update_employee" in c:

            empl_name = input("name>")
            empl_salary = input("monthly_salary>")
            empl_bonus = input("yearly_bonus>")
            empl_position = input("position>")

            empl_id = c[16:]
            cursor.execute(update, (empl_name, empl_salary, empl_bonus, empl_position, empl_id))
            connection.commit()

if __name__ == '__main__':
    main()


import random
name = input ("enter your name: ")
age= (int(input("enter your age: ")))
counter = 0
number1 = random.randint(1,10)
if age <= 18:
    while counter < 3:
        print (number1)
        guess = (int(input("pick a number between 1-10: ")))
        if guess == number1:
            print ("well done")
            break
        else:
            print("incorrect")
            counter = counter + 1


from collections import Counter
from itertools import accumulate

class Solution:
    """
    More thoughts...
    """
    def sumOfFlooredPairs(self, nums):
        nd = Counter(nums)
        inds = [0]*(max(nums)+1)

        # key part
        for n in nd:
            for i in range(n, len(inds), n):
                inds[i] += nd[n]
        pren = list(accumulate(inds))

        return int(sum([pren[n]*nd[n] for n in nd])%(10**9+7))

test = Solution()
nums = [7,7,7,7,7,7,7]
# nums = [2,5,9]
res = test.sumOfFlooredPairs(nums)
print(res)


import sqlite3
from dataclasses import asdict

from nicegui import ui

from app.types import BattingAverage, BowlingAverage, Player, Season, SeasonRecord

def show_season(db: sqlite3.Connection, year: int) -> None:
    min_innings = 5
    min_wickets = 10
    players = Player.all(db)

    with ui.header(elevated=True).style("background-color: maroon"):
        ui.label(f"{year} Season").style("color: gold")

    with ui.left_drawer():
        with ui.column():
            ui.link("Hundreds", "/hundreds")

    with ui.row():
        season = Season.for_year(db, year)
        ui.table(rows=[asdict(season)], columns=Season.table_cols()).props("dense")
    with ui.row():
        records = [row.row_dict() for row in SeasonRecord.for_year(db, year)]
        ui.table(rows=records, columns=SeasonRecord.table_cols()).props("dense")
    with ui.row():
        with ui.card():
            averages, also_batted = BattingAverage.for_year(db, year, min_innings)
            show_batting(min_innings, players, averages, show_position=True)
            show_batting(min_innings, players, also_batted, show_position=False)
        with ui.card():
            bowl_aves, also_bowled = BowlingAverage.for_year(db, year, min_wickets)
            show_bowling(min_wickets, players, bowl_aves, show_position=True)
            show_bowling(min_wickets, players, also_bowled, show_position=False)
        with ui.card():
            ui.label("other stats")

def show_batting(min_innings, players, averages, show_position=True):
    for average in averages:
        average.name = players[average.player_id].name
    records = [asdict(row) for row in averages]
    table = ui.table(
        rows=records,
        columns=BattingAverage.table_cols(),
        title=f"Batting (min {min_innings} innings)"
        if show_position
        else "Also batted",
    ).props("dense")

    table.add_slot(
        "body-cell-name",
        r"""

                    {{props.row.name}}

                """,
    )
    if not show_position:
        table.add_slot(
            "body-cell-position",
            r""" 	""",
        )

def show_bowling(min_wickets, players, averages, show_position=True):
    for average in averages:
        average.name = players[average.player_id].name
    records = [asdict(row) for row in averages]
    with ui.table(
        rows=records,
        columns=BowlingAverage.table_cols(),
        title=f"Bowling (min {min_wickets} wickets)"
        if show_position
        else "Also bowled",
    ).props("dense") as table:
        table.add_slot(
            "body-cell-name",
            r"""

                    {{props.row.name}}

                """,
        )
        if not show_position:
            table.add_slot(
                "body-cell-position",
                r""" 	""",
            )


import weakref
from pyroute2.common import basestring
from pyroute2.netlink.rtnl.ifinfmsg import ifinfmsg

class Interface(dict):

    table = 'interfaces'

    def __init__(self, db, key):
        self.db = db
        self.event_map = {ifinfmsg: "load_ifinfmsg"}
        self.kspec = ('target', ) + db.indices[self.table]
        self.schema = ('target', ) + \
            tuple(db.schema[self.table].keys())
        self.names = tuple((ifinfmsg.nla2name(x) for x in self.schema))
        self.key = self.complete_key(key)
        self.changed = set()
        self.load_sql()

    def __setitem__(self, key, value):
        self.changed.add(key)
        dict.__setitem__(self, key, value)

    def snapshot(self):
        snp = type(self)(self.db, self.key)
        self.db.save_deps(self.table, id(snp), weakref.ref(snp))
        return snp

    def complete_key(self, key):
        if isinstance(key, dict):
            ret_key = key
        else:
            ret_key = {'target': 'localhost'}

        if isinstance(key, basestring):
            ret_key['IFLA_IFNAME'] = key
        elif isinstance(key, int):
            ret_key['index'] = key

        fetch = []
        for name in self.kspec:
            if name not in ret_key:
                fetch.append('f_%s' % name)

        if fetch:
            keys = []
            values = []
            for name, value in ret_key.items():
                keys.append('f_%s = ?' % name)
                values.append(value)
            spec = (self
                    .db
                    .execute('SELECT %s FROM interfaces WHERE %s' %
                             (' , '.join(fetch), ' AND '.join(keys)),
                             values)
                    .fetchone())
            for name, value in zip(fetch, spec):
                ret_key[name[2:]] = value

        return ret_key

    def update(self, data):
        for key, value in data.items():
            self.load_value(key, value)

    def load_value(self, key, value):
        if key not in self.changed:
            dict.__setitem__(self, key, value)

    def load_ifinfmsg(self, target, event):
        # TODO: partial match (object rename / restore)
        # ...

        # full match
        for name, value in self.key.items():
            if name == 'target':
                if value != target:
                    return
            elif value != (event.get_attr(name) or event.get(name)):
                return
        #
        # load the event
        for name in self.schema:
            value = event.get_attr(name) or event.get(name)
            if value is not None:
                self.load_value(ifinfmsg.nla2name(name), value)

    def load_sql(self):
        keys = []
        values = []
        for name, value in self.key.items():
            keys.append('f_%s = ?' % name)
            values.append(value)
        spec = (self
                .db
                .execute('SELECT * FROM interfaces WHERE %s' %
                         ' AND '.join(keys), values)
                .fetchone())
        self.update(dict(zip(self.names, spec)))
        return self


from flask import Flask, render_template, flash, request, redirect, url_for
from flask_wtf.file import FileField, FileRequired
from werkzeug.utils import secure_filename
from werkzeug.datastructures import CombinedMultiDict
from wtforms import Form, TextField, SelectField, TextAreaField, validators, StringField,\
     SubmitField, RadioField
import decode_text
import logging
from local_defs import mydefs
import os
import time
from logging.handlers import RotatingFileHandler
# App config.
baseurl2 = 'doc.darkphoenix.net:5555'
DEBUG = True
app = Flask(__name__)
app.config.from_object(__name__)
app.config['SECRET_KEY'] = '7d441f27d441f27567d441f2b6176a'
app.config['UPLOAD_FOLDER'] = mydefs.UPLOAD_FOLDER

class text_decoder(Form):
    mapFile_1 = SelectField(u'Code Type', choices=mydefs.IMAGE_TYPE)
    mapFile_2 = SelectField(u'Version', choices=mydefs.RELEASE)
    mapFile_3 = SelectField(u'Version', choices=mydefs.PATCH_LETTER)
    mapFile_4 = SelectField(u'Version', choices=mydefs.PATCH_SPECIAL)
    # mapfile = TextField('Mapfile:', validators=[validators.required()])
    file = FileField('File:')

class text_decoder_nofile(Form):
    mapFile_1 = SelectField(u'Code Type', choices=mydefs.IMAGE_TYPE)
    mapFile_2 = SelectField(u'Version', choices=mydefs.RELEASE)
    mapFile_3 = SelectField(u'Version', choices=mydefs.PATCH_LETTER)
    mapFile_4 = SelectField(u'Version', choices=mydefs.PATCH_SPECIAL)
    stack_output = TextAreaField('stack_output', validators=[validators.Required()])

class gen_script(Form):
    # script_lan = SelectField(u'Script Language', choices=mydefs.SCRIPT_LANGUAGES)
    target_ip = TextField('Target IP', validators=[validators.Required()])
    access_type = RadioField('Access Type:', choices=[('ssh', 'ssh'),\
                        ('telnet','telnet')])
    authen_t = RadioField('Authentication:',choices=[\
    ('implicit','implicit'),('UserEnable','UserEnable'),\
    ('NoneEnable','NoneEnable'),('None','None')])
    command_trig = TextField('Trigger Command: ', validators=[validators.Required()])
    trig_type = RadioField('Trigger Type: ', choices=[\
    ('Text Pattern','Text Pattern'),('Conditional','Conditional')])
    trig_value = TextField('Trigger Value:')

@app.route("/", methods=['GET', 'POST'])
def base_page():
    return render_template('base.html')

@app.route("/text_decode", methods=['GET', 'POST'])
def text_decode():
    form = text_decoder(request.form)
    # print(form.errors)
    if request.method == 'POST':
        print('Got here 1')
        f = request.files['file']
        print('f is ', f)
        filename = secure_filename(f.filename)
        print('Got here 2')
        fs = f.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        stackfile = mydefs.UPLOAD_FOLDER + '/' + filename
        mapfile = mydefs.MAP_ROOT + request.form['mapFile_2'] +\
                   '/LATEST_BUILD/dist' + request.form['mapFile_1'] +\
                   'prod.map'
        map_timestamp = time.ctime(os.path.getmtime(mapfile))
        temp_mappath =  request.form['mapFile_2'] +\
                   '/LATEST_BUILD/dist' + request.form['mapFile_1'] +\
                   'prod.map'
        print('Got here 3')
        print('Got here 3.5')
        print('Form Validation ', form.validate())
        print('Form errors ', form.errors)
        print('filename is ', filename)
        print('fs is', fs)
        print('stackfile is', stackfile)
        print('mapfile is', mapfile)
        if form.validate():
            flash('Okay now will decode')
            print('Got here 4')
            d_result = decode_text.decode_t(mapfile, stackfile, '1',\
                                            map_timestamp, temp_mappath)
            print("Result is ", d_result)
            return render_template('results.html', result=d_result)
        else:
            flash('Error: All the form fields are required. ')
            return redirect('/text_decode')
    return render_template('t_decode.html', form=form)

@app.route("/text_decode_nofile", methods=['GET', 'POST'])
def text_decode_nofile():
    form = text_decoder_nofile(request.form)

    print(form.errors)
    if request.method == 'POST':
        print('Got here 1')

        print('Got here 2')
        stack_output = request.form['stack_output']
        if request.form['mapFile_3'] is 'UNDEFINED':
            MAP_LETTER = request.form['mapFile_4']
        else:
            MAP_LETTER = request.form['mapFile_3']

        mapfile = mydefs.MAP_ROOT + request.form['mapFile_2'] + MAP_LETTER +\
                   '/LATEST_BUILD/dist' + request.form['mapFile_1'] +\
                   'prod.map'
        map_timestamp = time.ctime(os.path.getmtime(mapfile))
        temp_mappath =  request.form['mapFile_2'] +\
                   '/LATEST_BUILD/dist' + request.form['mapFile_1'] +\
                   'prod.map'
        print('timestamp is ',map_timestamp)
        print('mypath is', temp_mappath)
        print('Got here 3')
        print('Got here 3.5')
        print('Form Validation ', form.validate())
        print('Form errors ', form.errors)
        print('mapfile is', mapfile)
        if form.validate():
            flash('Okay now will decode')
            print('Got here 4')
            d_result = decode_text.decode_t(mapfile, stack_output, 0,\
                                            map_timestamp, temp_mappath)
            print("Result is ", d_result)
            return render_template('results.html', result=d_result)
        else:
            flash('Error: All the form fields are required. ')
            return redirect('/text_decode_nofile')
    return render_template('t_decode_nofile.html', form=form)

@app.route("/icx_decoder", methods=['GET', 'POST'])
def stack_decodenew():
    form = text_decoder(CombinedMultiDict((request.form, request.files)))
    # print(form.errors)
    if request.method == 'POST':
        print('Got here 1')
        f = request.files['file']
        print('f is ', f)
        filename = secure_filename(f.filename)
        print('Got here 2')
        fs = f.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        stackfile = mydefs.UPLOAD_FOLDER + '/' + filename
        print('Got here 3')
        if request.form['mapFile_3'] is 'UNDEFINED':
            MAP_LETTER = request.form['mapFile_4']
        else:
            MAP_LETTER = request.form['mapFile_3']

        mapfile = mydefs.MAP_ROOT + request.form['mapFile_2'] + MAP_LETTER +\
                   '/LATEST_BUILD/dist' + request.form['mapFile_1'] +\
                   'prod.map'
        if not os.path.isfile(mapfile):
            flash('Sorry this code image is not supported yet!')
            return redirect('/icx_decoder')

        map_timestamp = time.ctime(os.path.getmtime(mapfile))
        temp_mappath =  request.form['mapFile_2'] +\
                   '/LATEST_BUILD/dist' + request.form['mapFile_1'] +\
                   'prod.map'
        print('Got here 3.5')
        print('Form Validation ', form.validate())
        print('Form errors ', form.errors)
        print('filename is ', filename)
        print('fs is', fs)
        print('stackfile is', stackfile)
        print('mapfile is', mapfile)
        if form.validate():
            flash('Okay now will decode')
            print('Got here 4')
            d_result = decode_text.decode_corefile(mapfile, stackfile,\
                                                   map_timestamp, temp_mappath)
            print("Result is ", d_result)
            return render_template('results.html', result=d_result)
        else:
            flash('Error: All the form fields are required. ')
            return redirect('/icx_decoder')
    return render_template('stack_decodenew.html', form=form)

@app.route('/result', methods=['GET', 'POST'])
def result():
    if request.method == 'POST':
        result = request.form
        return render_template('results.html', result=d_result)
    else:
        return redirect('/')

if __name__ == "__main__":
    handler = RotatingFileHandler('web.log', maxBytes=10000, backupCount=1)
    handler.setLevel(logging.INFO)
    app.logger.addHandler(handler)
    app.run(host='0.0.0.0', port=5555)


import os
import sys

path_data = sys.argv[1]

list_activity = ['antibacterial', 'antimicrobial', 'Antibiofilm','Antifungal', 'AntiGram_n','AntiGram_p', 'AntiHIV','Antiinflammatory', 'Antimalarial','AntiMRSA', 'Antioncogenic','Antioxidant', 'Antiparasitic','Antiprotozoal', 'anti_tb','Antitumour', 'Antiviral','Antiyeast', 'bacteriocins','CancerCells', 'Chemotactic','defense', 'EnzymeInhibitor','Immunomodulatory','Insecticidal','MammalianCells','milk_peptide','quorom_sense','Spermicidal','SurfaceImmobilized','WoundHealing']
list_save_results = ["embedding-graph", "embedding-unsupervised", "FFT-graph", "FFT-time-series", "PCA-embedding-graph", "PCA-embedding-unsupervised"]

for activity in list_activity:
	command = "mkdir -p %s%s" % (path_data, activity)
	print(command)
	os.system(command)

	for results in list_save_results:
		command = "mkdir -p %s%s/%s" % (path_data, activity, results)
		print(command)
		os.system(command)

		if "FFT" in results:
			for property_value in ["alpha-structure_group", "betha-structure_group", "energetic_group", "hydropathy_group", "hydrophobicity_group", "index_group", "secondary_structure_properties_group", "volume_group"]:
				command = "mkdir -p %s%s/%s/%s" % (path_data, activity, results, property_value)
				print(command)
				os.system(command)


class Solution:
    def minDifference(self, nums: List[int]) -> int:
        if len(nums) <= 4:
            return 0
        else:
            n = len(nums)
            nums.sort()
            S=[]

            for k in range(4):
                for j in range(4-k):
                    S.append( nums[n-1-j]-nums[k]  )

            return min(S)


# Given an integer array nums, return the length of the longest strictly increasing subsequence.

# A subsequence is a sequence that can be derived from an array by deleting some or no elements without changing the order of the remaining elements. For example, [3,6,2,7] is a subsequence of the array [0,3,1,6,2,2,7].

# Example 1:

# Input: nums = [10,9,2,5,3,7,101,18]
# Output: 4
# Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.
# Example 2:

# Input: nums = [0,1,0,3,2,3]
# Output: 4
# Example 3:

# Input: nums = [7,7,7,7,7,7,7]
# Output: 1

# Constraints:

# 1 <= nums.length <= 2500
# -104 <= nums[i] <= 104

# time complexity(n^2)
class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        if len(nums) == 0:
            return 0
        # generate a dp array
        dp = [1] * len(nums)
        # max subsequence
        res = 1
        # traverse the nums
        for i in range(len(nums)):
            for j in range(i):
                # if the current pointer i greater than the prevous pointer j, then take max length of dp[i] and dp[j] + 1
                if nums[i] > nums[j]:
                    dp[i] = max(dp[i], dp[j]+1)
            # find the max subsequence
            res = max(res, dp[i])

        return res

# time complexity(nlongn)
class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        import bisect
        dp = []
        for x in nums:
            # return the insection index on nums
            i = bisect_left(dp,x)
            if i == len(dp):
                dp.append(x)
            else:
                dp[i] = x
        print(dp)
        return len(dp)

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        dp = [1] * len(nums)
        for i in range(len(nums)):
            for j in range(i):
                if nums[i] > nums[j]:
                    dp[i] = max(dp[i], dp[j] + 1)
        return max(dp)


from django.urls import path
from todolist.views import *

app_name = 'todolist'

urlpatterns = [
    path('', show_todolist, name='show_todolist'),
    path('json/', show_json_todo, name='show_json_todo'),
    path('add/', create_task_ajax, name='create_task_ajax'),
    path('login/', login_user, name='login'),
    path('register/', register, name='register'),
    path('create-task/', create_task, name='create_task'),
    path('logout/', logout_user, name='logout'),
]


import sys

input = sys.stdin.readline

stack = []

T = int(input())

for _ in range(T):
    a, word = input().split()
    for i in range(len(word)):
        for j in range(int(a)):
            print(word[i], end="")
    print()


import tkinter as tk
from tkinter import *
from tkinter.messagebox import showinfo
import os

root = Tk()
root.title = ("app")
root.geometry = ('400x580')

def hati_kosong():
    showinfo(title='INFO', message='Terisi')
    if showinfo == True:
        hati_penuh()
    else:
        return hatikosong()
def hati_penuh():
    showinfo(title='info', message='sudah penuh')

#button hatikosong
hatikosong = PhotoImage(file="./gambar/hatikosong.png")
button_hatikosong = Button(root, image=hatikosong,borderwidth=0, cursor="hand2", command=hati_kosong)
button_hatikosong.place(x=2, y=3)

#button hatipenuh
hatipenuh= PhotoImage(file="./gambar/hatipenuh.png")
button_hatipenuh = Button(root, image=hatipenuh,borderwidth=0, cursor="hand2", command=hati_penuh)
button_hatipenuh.place(x=250, y=10)

#button out
keluar = PhotoImage(file="./gambar/out.png")
button_keluar = Button(root, image=keluar,borderwidth=0, cursor="hand2",command=root.destroy)
button_keluar.place(x=25, y=300)

root.mainloop()


import pandas as pd
import seaborn as sn
import matplotlib.pyplot as plt

test1 = pd.read_csv('/Users/Brova/Downloads/occupancy_data/datatest.txt')
test1 = test1.set_index('date')
test2 = pd.read_csv('/Users/Brova/Downloads/occupancy_data/datatest2.txt')
test2 = test2.set_index('date')

tests_combined = pd.concat([test1, test2])

testsFrame = pd.DataFrame(tests_combined, columns=["Temperature","Humidity","Light","CO2","HumidityRatio","Occupancy"])
corrMatrix = testsFrame.corr()
print(corrMatrix)

sn.heatmap(corrMatrix, annot=True)
plt.show()

Correlation_matrixes & Histograms (Code)/UCI/both_tests_correlation_matrix.py


# -*- coding: utf-8 -*-

import logging.config
import logging
import traceback

PLUGIN_NAME = 'SmojSubmit'

class SmojSubmitFormatter(logging.Formatter):
    def format(self, record):
        level = record.levelname[0]
        name = record.name
        if name.startswith(PLUGIN_NAME + '.'):
            name = name[len(PLUGIN_NAME) + 1 : ]
        if record.exc_info is not None:
            trace = ''.join(traceback.format_exception(*record.exc_info))
            s = PLUGIN_NAME + ': [{0} {1}:{2.lineno}] {2.msg}. Traceback:\n{3}'.format(level, name, record, trace)
        else:
            s = PLUGIN_NAME + ': [{0} {1}:{2.lineno}] {2.msg}'.format(level, name, record)
        return s

def init_logging():
    config = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'smojsubmit_fmt': {
                '()': __name__ + '.SmojSubmitFormatter'
            }
        },
        'handlers': {
            'smojsubmit_handler': {
                'level': 'WARNING',
                'formatter': 'smojsubmit_fmt',
                'class': 'logging.StreamHandler',
                'stream': 'ext://sys.stderr'
            }
        },
        'loggers': {
            'SmojSubmit': {
                'handlers': ['smojsubmit_handler'],
                'level': 'WARNING',
                'propagate': False
            }
        }
    }
    logging.config.dictConfig(config)

    logger = logging.getLogger(__name__)
    logger.info('logging initialized')


import discord
from discord import app_commands
import morsecode
import caesarcode

token = 'xxxxxxxxxxxxxxxxxxx'
intents = discord.Intents.default()
client = discord.Client(intents=intents)
tree = app_commands.CommandTree(client)

@client.event
async def on_ready():
    await tree.sync(guild=discord.Object(id=1109016227210350634))
    print("DisCipher up")

@tree.command(name = "morse-encode", description = "encodes from english to morse", guild=discord.Object(id=1109016227210350634))
async def encoding(interaction: discord.Interaction, input: str) -> None:
    await interaction.response.send_message(morsecode.encode(input))

@tree.command(name = "morse-decode", description = "decodes from morse  to english", guild=discord.Object(id=1109016227210350634))
async def decoding(interaction: discord.Interaction, input: str) -> None:
    await interaction.response.send_message(morsecode.decode(input))

@tree.command(name = "caesar-encode", description = "encodes from english to caesar cipher", guild=discord.Object(id=1109016227210350634))
async def encoding(interaction: discord.Interaction, shifting: int, *, input: str) -> None:
    await interaction.response.send_message(caesarcode.encode(shifting, input))

@tree.command(name = "caesar-decode", description = "decodes from caeser cipher to english", guild=discord.Object(id=1109016227210350634))
async def encoding(interaction: discord.Interaction, shifting: int, *, input: str) -> None:
    await interaction.response.send_message(caesarcode.decode(shifting, input))

@tree.command(name = "rot13-encode", description = "encodes from english to ROT13", guild=discord.Object(id=1109016227210350634))
async def encoding(interaction: discord.Interaction, input: str) -> None:
    await interaction.response.send_message(caesarcode.rot3encode(input))

@tree.command(name = "rot13-decode", description = "decodes from ROT13 to english", guild=discord.Object(id=1109016227210350634))
async def encoding(interaction: discord.Interaction, input: str) -> None:
    await interaction.response.send_message(caesarcode.rot3decode(input))

client.run(token)


def convert(inFilename, outFilename, typeDict):
    outfile = open(outFilename, "w")
    contentArr = open(inFilename, "r").readlines()
    for lineId, line in enumerate(contentArr):
        sentStr, tagStr = line.rstrip("\n").split("\t")[:2]
        wordArr = sentStr.split(" ")
        tagArr = [typeDict[wordTag] if wordTag != "O" else wordTag for wordTag in tagStr.split(" ")]
        for word, wordTag in zip(wordArr, tagArr):
            outfile.write(word+" "+wordTag+"\n")
        if lineId < len(contentArr)-1: outfile.write("\n")

    outfile.close()

if __name__ == "__main__":

    arr = open("./ACE_event_types.txt").readlines()
    arr = [line.rstrip("\n").split("\t") for line in arr]
    typeDict = dict([(line[0], "B-"+line[2]) for line in arr])
    label_out_file = open("labels.txt", "w")
    label_out_file.write("\n".join(sorted(typeDict.values())))
    label_out_file.close()

    convert("./cn_trig_ner_arg.train.txt", "train.txt", typeDict)
    convert("./cn_trig_ner_arg.dev.txt", "dev.txt", typeDict)
    convert("./cn_trig_ner_arg.test.txt", "test.txt", typeDict)


#!/usr/bin/python
# -*- coding: utf-8 -*-
# pylint: disable=c0209, r0902, r0912, r0913, r0915
""" certificate class """
from __future__ import print_function
import json
from acme_srv.helper import b64_url_recode, generate_random_string, cert_san_get, cert_extensions_get, hooks_load, uts_now, uts_to_date_utc, date_to_uts_utc, load_config, csr_san_get, csr_extensions_get, cert_dates_get, ca_handler_load, error_dic_get, string_sanitize, pembundle_to_list, certid_asn1_get
from acme_srv.db_handler import DBstore
from acme_srv.message import Message
from acme_srv.threadwithreturnvalue import ThreadWithReturnValue

class Certificate(object):
    """ CA  handler """

    def __init__(self, debug=None, srv_name=None, logger=None):
        self.debug = debug
        self.server_name = srv_name
        self.logger = logger
        self.cahandler = None
        self.dbstore = DBstore(self.debug, self.logger)
        self.err_msg_dic = error_dic_get(self.logger)
        self.hooks = None
        self.ignore_pre_hook_failure = False
        self.ignore_post_hook_failure = True
        self.ignore_success_hook_failure = False
        self.message = Message(self.debug, self.server_name, self.logger)
        self.path_dic = {'cert_path': '/acme/cert/'}
        self.retry_after = 600
        self.tnauthlist_support = False
        self.cert_reusage_timeframe = 0
        self.enrollment_timeout = 5

    def __enter__(self):
        """ Makes ACMEHandler a Context Manager """
        self._config_load()
        return self

    def __exit__(self, *args):
        """ cose the connection at the end of the context """

    def _account_check(self, account_name, certificate):
        """ check account """
        self.logger.debug('Certificate.issuer_check()')
        try:
            result = self.dbstore.certificate_account_check(account_name, b64_url_recode(self.logger, certificate))
        except Exception as err_:
            self.logger.critical('acme2certifier database error in Certificate._account_check(): {0}'.format(err_))
            result = None
        return result

    def _authz_check(self, identifier_dic, certificate):
        self.logger.debug('Certificate._authz_check()')
        # load identifiers
        try:
            identifiers = json.loads(identifier_dic['identifiers'].lower())
        except Exception:
            identifiers = []

        # check if we have a tnauthlist identifier
        tnauthlist_identifer_in = self._tnauth_identifier_check(identifiers)
        if self.tnauthlist_support and tnauthlist_identifer_in:
            try:
                # get list of certextensions in base64 format and identifier status
                tnauthlist = cert_extensions_get(self.logger, certificate)
                identifier_status = self._identifer_tnauth_list(identifier_dic, tnauthlist)
            except Exception as err_:
                # enough to set identifier_list as empty list
                identifier_status = []
                self.logger.warning('Certificate._authorization_check() error while loading parsing certifcate. Error: {0}'.format(err_))
        else:
            try:
                # get sans
                san_list = cert_san_get(self.logger, certificate)
                identifier_status = self._identifer_status_list(identifiers, san_list)
            except Exception as err_:
                # enough to set identifier_list as empty list
                identifier_status = []
                self.logger.warning('Certificate._authorization_check() error while loading parsing certifcate. Error: {0}'.format(err_))

        self.logger.debug('Certificate._authz_check() ended')
        return identifier_status

    def _authorization_check(self, order_name, certificate):
        """ check if an acount holds authorization for all identifiers = SANs in the certificate """
        self.logger.debug('Certificate._authorization_check()')

        # empty list of statuses
        identifier_status = []

        # get identifiers for order
        try:
            identifier_dic = self.dbstore.order_lookup('name', order_name, ['identifiers'])
        except Exception as err_:
            self.logger.critical('acme2certifier database error in Certificate._authorization_check(): {0}'.format(err_))
            identifier_dic = {}

        if identifier_dic and 'identifiers' in identifier_dic:
            # get identifier status list
            identifier_status = self._authz_check(identifier_dic, certificate)

        result = False
        if identifier_status and False not in identifier_status:
            result = True

        self.logger.debug('Certificate._authorization_check() ended with {0}'.format(result))
        return result

    def _cert_reusage_check(self, csr):
        """ check if an existing certificate an be reused """
        self.logger.debug('Certificate._cert_reusage_check({0})'.format(self.cert_reusage_timeframe))

        try:
            result_dic = self.dbstore.certificates_search('csr', csr, ('cert', 'cert_raw', 'expire_uts', 'issue_uts', 'created_at', 'id'))
        except Exception as err_:
            self.logger.critical('acme2certifier database error in Certificate._cert_reusage_check(): {0}'.format(err_))
            result_dic = None

        cert = None
        cert_raw = None
        message = None

        if result_dic:
            uts = uts_now()
            # sort certificates by creation date
            for certificate in sorted(result_dic, key=lambda i: i['issue_uts'], reverse=True):
                try:
                    uts_create = date_to_uts_utc(certificate['created_at'])
                except Exception as _err:
                    self.logger.error('acme2certifier date_to_uts_utc() error in Certificate._cert_reusage_check(): id:{0}/created_at:{1}'.format(certificate['id'], certificate['created_at']))
                    uts_create = 0

                # check if there certificates within reusage timeframe
                if certificate['cert_raw'] and certificate['cert'] and uts - self.cert_reusage_timeframe <= uts_create:
                    # exclude expired certificates
                    if uts <= certificate['expire_uts']:
                        cert = certificate['cert']
                        cert_raw = certificate['cert_raw']
                        message = 'reused certificate from id: {0}'.format(certificate['id'])
                        break

        self.logger.debug('Certificate._cert_reusage_check() ended with {0}'.format(message))
        return (None, cert, cert_raw, message)

    def _config_hooks_load(self, config_dic):
        """ load hook configuration """
        self.logger.debug('Certificate._config_hooks_load()')

        # load hooks according to configuration
        hooks_module = hooks_load(self.logger, config_dic)
        if hooks_module:
            try:
                # store handler in variable
                self.hooks = hooks_module.Hooks(self.logger)
            except Exception as err:
                self.logger.critical('Certificate._config_load(): Hooks could not be loaded: {0}'.format(err))

            self.ignore_pre_hook_failure = config_dic.getboolean('Hooks', 'ignore_pre_hook_failure', fallback=False)
            self.ignore_post_hook_failure = config_dic.getboolean('Hooks', 'ignore_post_hook_failure', fallback=True)
            self.ignore_success_hook_failure = config_dic.getboolean('Hooks', 'ignore_success_hook_failure', fallback=False)

        self.logger.debug('Certificate._config_hooks_load() ended')

    def _config_parameters_load(self, config_dic):
        """ load various parameters """
        self.logger.debug('Certificate._config_parameters_load()')

        if 'Certificate' in config_dic:
            if 'cert_reusage_timeframe' in config_dic['Certificate']:
                try:
                    self.cert_reusage_timeframe = int(config_dic['Certificate']['cert_reusage_timeframe'])
                except Exception as err_:
                    self.logger.error('acme2certifier Certificate._config_load() cert_reusage_timout parsing error: {0}'.format(err_))
            if 'enrollment_timeout' in config_dic['Certificate']:
                try:
                    self.enrollment_timeout = int(config_dic['Certificate']['enrollment_timeout'])
                except Exception as err_:
                    self.logger.error('acme2certifier Certificate._config_load() enrollment_timeout parsing error: {0}'.format(err_))

        if 'Directory' in config_dic and 'url_prefix' in config_dic['Directory']:
            self.path_dic = {k: config_dic['Directory']['url_prefix'] + v for k, v in self.path_dic.items()}

        self.logger.debug('Certificate._config_parameters_load() ended')

    def _config_load(self):
        """" load config from file """
        self.logger.debug('Certificate._config_load()')
        config_dic = load_config()
        if 'Order' in config_dic:
            self.tnauthlist_support = config_dic.getboolean('Order', 'tnauthlist_support', fallback=False)

        # load ca_handler according to configuration
        ca_handler_module = ca_handler_load(self.logger, config_dic)

        if ca_handler_module:
            # store handler in variable
            self.cahandler = ca_handler_module.CAhandler
        else:
            self.logger.critical('Certificate._config_load(): No ca_handler loaded')

        # load hooks
        self._config_hooks_load(config_dic)

        # load parametrs
        self._config_parameters_load(config_dic)

        self.logger.debug('ca_handler: {0}'.format(ca_handler_module))
        self.logger.debug('Certificate._config_load() ended.')

    def _identifiers_load(self, identifier_dic, csr):
        self.logger.debug('Certificate._identifiers_load()')
        # load identifiers
        try:
            identifiers = json.loads(identifier_dic['identifiers'].lower())
        except Exception:
            identifiers = []

        # do we need to check for tnauth
        tnauthlist_identifer_in = self._tnauth_identifier_check(identifiers)

        if self.tnauthlist_support and tnauthlist_identifer_in:
            # get list of certextensions in base64 format
            try:
                tnauthlist = csr_extensions_get(self.logger, csr)
                identifier_status = self._identifer_tnauth_list(identifier_dic, tnauthlist)
            except Exception as err_:
                identifier_status = []
                self.logger.warning('Certificate._csr_check() error while parsing csr.\nerror: {0}'.format(err_))
        else:
            # get sans and compare identifiers against san
            try:
                san_list = csr_san_get(self.logger, csr)
                identifier_status = self._identifer_status_list(identifiers, san_list)
            except Exception as err_:
                identifier_status = []
                self.logger.warning('Certificate._csr_check() error while checking csr.\nerror: {0}'.format(err_))

        self.logger.debug('Certificate._identifiers_load() ended with {0}'.format(identifier_status))
        return identifier_status

    def _csr_check(self, certificate_name, csr):
        """ compare csr extensions against order """
        self.logger.debug('Certificate._csr_check()')

        # fetch certificate dictionary from DB
        certificate_dic = self._info(certificate_name)
        self.logger.debug('Certificate._info() ended with:{0}'.format(certificate_dic))

        # empty list of statuses
        identifier_status = []

        if 'order' in certificate_dic:
            # get identifiers for order
            try:
                identifier_dic = self.dbstore.order_lookup('name', certificate_dic['order'], ['identifiers'])
            except Exception as err_:
                self.logger.critical('acme2certifier database error in Certificate._csr_check(): {0}'.format(err_))
                identifier_dic = {}

            if identifier_dic and 'identifiers' in identifier_dic:
                identifier_status = self._identifiers_load(identifier_dic, csr)

        csr_check_result = False

        if identifier_status and False not in identifier_status:
            csr_check_result = True

        self.logger.debug('Certificate._csr_check() ended with {0}'.format(csr_check_result))
        return csr_check_result

    def _enroll(self, csr, ca_handler):

        if self.cert_reusage_timeframe:
            (error, certificate, certificate_raw, poll_identifier) = self._cert_reusage_check(csr)
        else:
            certificate = None
            certificate_raw = None

        if not certificate or not certificate_raw:
            self.logger.debug('Certificate._enroll_and_store(): trigger enrollment')
            (error, certificate, certificate_raw, poll_identifier) = ca_handler.enroll(csr)
        else:
            self.logger.info('Certificate._enroll_and_store(): reuse existing certificate')

        return (error, certificate, certificate_raw, poll_identifier)

    def _renewal_info_get(self, certificate):
        """ get renewal info """
        self.logger.error('Certificate._renewal_info_get()')

        certificate_list = pembundle_to_list(self.logger, certificate)

        renewal_info_hex = certid_asn1_get(self.logger, certificate_list[0], certificate_list[1])

        self.logger.debug('Certificate.certid_asn1_get() ended with {0}'.format(renewal_info_hex))
        return renewal_info_hex

    def _store(self, certificate, certificate_raw, poll_identifier, certificate_name, order_name, csr):

        error = None

        (issue_uts, expire_uts) = cert_dates_get(self.logger, certificate_raw)
        try:
            result = self._store_cert(certificate_name, certificate, certificate_raw, issue_uts, expire_uts, poll_identifier)
            if result:
                self._order_update({'name': order_name, 'status': 'valid'})
            if self.hooks:
                try:
                    self.hooks.success_hook(certificate_name, order_name, csr, certificate, certificate_raw, poll_identifier)
                    self.logger.debug('Certificate._enroll_and_store: success_hook successful')
                except Exception as err:
                    self.logger.error('Certificate._enroll_and_store: success_hook exception: {0}'.format(err))
                    if not self.ignore_success_hook_failure:
                        error = (None, 'success_hook_error', str(err))

        except Exception as err_:
            result = None
            self.logger.critical('acme2certifier database error in Certificate._enroll_and_store(): {0}'.format(err_))

        return (result, error)

    def _enrollerror_handler(self, error, poll_identifier, order_name, certificate_name):
        """ store error message for later analysis """
        self.logger.error('Certificate._enroll_and_store({0})'.format(error))

        result = None
        detail = None

        try:
            if not poll_identifier:
                self.logger.debug('Certificate._enroll_and_store(): invalidating order as there is no certificate and no poll_identifier: {0}/{1}'.format(error, order_name))
                self._order_update({'name': order_name, 'status': 'invalid'})
            self._store_cert_error(certificate_name, error, poll_identifier)
        except Exception as err_:
            result = None
            self.logger.critical('acme2certifier database error in Certificate._enroll_and_store() _store_cert_error: {0}'.format(err_))

        # cover polling cases
        if poll_identifier:
            detail = poll_identifier
        else:
            error = self.err_msg_dic['serverinternal']

        self.logger.error('Certificate._enroll_and_store() ended with: {0}'.format(result))
        return (result, error, detail)

    def _pre_hooks_process(self, certificate_name, order_name, csr):
        self.logger.debug('Certificate._pre_hooks_process({0}, {1})'.format(certificate_name, order_name))
        hook_error = []
        if self.hooks:
            try:
                self.hooks.pre_hook(certificate_name, order_name, csr)
                self.logger.debug('Certificate._enroll_and_store(): pre_hook successful')
            except Exception as err:
                self.logger.error('Certificate._enroll_and_store(): pre_hook exception: {0}'.format(err))
                if not self.ignore_pre_hook_failure:
                    hook_error = (None, 'pre_hook_error', str(err))

        self.logger.debug('Certificate._pre_hooks_process({0})'.format(hook_error))
        return hook_error

    def _post_hooks_process(self, certificate_name, order_name, csr, error):
        self.logger.debug('Certificate._pre_hooks_process({0}, {1})'.format(certificate_name, order_name))

        hook_error = []
        if self.hooks:
            try:
                self.hooks.post_hook(certificate_name, order_name, csr, error)
                self.logger.debug('Certificate._enroll_and_store(): post_hook successful')
            except Exception as err:
                self.logger.error('Certificate._enroll_and_store(): post_hook exception: {0}'.format(err))
                if not self.ignore_post_hook_failure:
                    hook_error = (None, 'post_hook_error', str(err))

        self.logger.debug('Certificate._post_hooks_process({0})'.format(hook_error))
        return hook_error

    def _enroll_and_store(self, certificate_name, csr, order_name=None):
        """ enroll and store certificate """
        self.logger.debug('Certificate._enroll_and_store({0}, {1}, {2})'.format(certificate_name, order_name, csr))

        detail = None
        error = None

        hook_error = self._pre_hooks_process(certificate_name, order_name, csr)
        if hook_error:
            return hook_error

        with self.cahandler(self.debug, self.logger) as ca_handler:

            # enroll certificate
            (error, certificate, certificate_raw, poll_identifier) = self._enroll(csr, ca_handler)

            if certificate:
                (result, error) = self._store(certificate, certificate_raw, poll_identifier, certificate_name, order_name, csr)
                if error:
                    return error
            else:
                self.logger.error('acme2certifier enrollment error: {0}'.format(error))
                (result, error, detail) = self._enrollerror_handler(error, poll_identifier, order_name, certificate_name)

        hook_error = self._post_hooks_process(certificate_name, order_name, csr, error)
        if hook_error:
            return hook_error

        self.logger.debug('Certificate._enroll_and_store() ended with: {0}:{1}'.format(result, error))
        return (result, error, detail)

    def _identifier_chk(self, cert_type, cert_value, identifiers, san_is_in):
        """ check identifier """
        self.logger.debug('Certificate._identifier_chk({0}/{1})'.format(cert_type, cert_value))

        if cert_type and cert_value:
            for identifier in identifiers:
                if 'type' in identifier:
                    if (identifier['type'].lower() == cert_type and identifier['value'].lower() == cert_value):
                        san_is_in = True
                        break

        self.logger.debug('Certificate._identifier_chk({0})'.format(san_is_in))
        return san_is_in

    def _identifer_status_list(self, identifiers, san_list):
        """ compare identifiers and check if each san is in identifer list """
        self.logger.debug('Certificate._identifer_status_list()')

        identifier_status = []
        for san in san_list:
            san_is_in = False
            try:
                (cert_type, cert_value) = san.lower().split(':', 1)
            except Exception as err_:
                self.logger.error('Error while splitting san {0}: {1}'.format(san, err_))
                cert_type = None
                cert_value = None

            # check identifiers
            san_is_in = self._identifier_chk(cert_type, cert_value, identifiers, san_is_in)

            self.logger.debug('SAN check for {0} against identifiers returned {1}'.format(san.lower(), san_is_in))
            identifier_status.append(san_is_in)

        if not identifier_status:
            identifier_status.append(False)

        self.logger.debug('Certificate._identifer_status_list() ended with {0}'.format(identifier_status))
        return identifier_status

    def _identifier_tnauth_chk(self, identifier, tnauthlist):
        """ check tnauth identifier against tnauthlist """
        self.logger.debug('Certificate._identifier_tnauth_chk({0})'.format(identifier))

        result = False
        # get the tnauthlist identifier
        if 'type' in identifier and identifier['type'].lower() == 'tnauthlist':
            # check if tnauthlist extension is in extension list
            if 'value' in identifier and identifier['value'] in tnauthlist:
                result = True

        self.logger.debug('Certificate._identifier_tnauth_chk() endedt with {0}'.format(result))
        return result

    def _identifer_tnauth_list(self, identifier_dic, tnauthlist):
        """ compare identifiers and check if each san is in identifer list """
        self.logger.debug('Certificate._identifer_tnauth_list()')

        identifier_status = []
        # reload identifiers (case senetive)
        try:
            identifiers = json.loads(identifier_dic['identifiers'])
        except Exception:
            identifiers = []

        if tnauthlist and not identifier_dic:
            identifier_status.append(False)
        elif identifiers and tnauthlist:
            for identifier in identifiers:
                identifier_status.append(self._identifier_tnauth_chk(identifier, tnauthlist))
        else:
            identifier_status.append(False)

        self.logger.debug('Certificate._identifer_tnauth_list() ended with {0}'.format(identifier_status))
        return identifier_status

    def _info(self, certificate_name, flist=('name', 'csr', 'cert', 'order__name')):
        """ get certificate from database """
        self.logger.debug('Certificate._info({0})'.format(certificate_name))
        try:
            result = self.dbstore.certificate_lookup('name', certificate_name, flist)
        except Exception as err_:
            self.logger.critical('acme2certifier database error in Certificate._info(): {0}'.format(err_))
            result = None
        return result

    def _expirydate_assume(self, cert, timestamp, to_be_cleared):
        """ assume expiry date """
        self.logger.debug('Certificate._expirydate_assume()')

        if 'csr' in cert and cert['csr']:
            # cover cases for enrollments in flight
            # we assume that a CSR should turn int a cert within two weeks
            if 'created_at' in cert:
                created_at_uts = date_to_uts_utc(cert['created_at'])
                if 0 < created_at_uts < timestamp - (14 * 86400):
                    to_be_cleared = True
            else:
                # this scneario should never been happen so lets be careful and not clear it
                to_be_cleared = False
        else:
            # no csr and no cert - to be cleared
            to_be_cleared = True

        self.logger.debug('Certificate._expirydate_assume() ended')
        return to_be_cleared

    def _expiredate_get(self, cert, timestamp, to_be_cleared):
        """ get expirey date from certificate """
        self.logger.debug('Certificate._expiredate_get()')

        # in case cert_expiry in table is 0 try to get it from cert
        if cert['expire_uts'] == 0:
            if 'cert_raw' in cert and cert['cert_raw']:
                # get expiration from certificate
                (issue_uts, expire_uts) = cert_dates_get(self.logger, cert['cert_raw'])
                if 0 < expire_uts < timestamp:
                    # returned date is other than 0 and lower than given timestamp
                    cert['issue_uts'] = issue_uts
                    cert['expire_uts'] = expire_uts
                    to_be_cleared = True
            else:
                to_be_cleared = self._expirydate_assume(cert, timestamp, to_be_cleared)
        else:
            # expired based on expire_uts from db
            to_be_cleared = True

        self.logger.debug('Certificate._expiredate_get() ended with: to_be_cleared:  {0}'.format(to_be_cleared))
        return to_be_cleared

    def _invalidation_check(self, cert, timestamp, purge=False):
        """ check if cert must be invalidated """
        if 'name' in cert:
            self.logger.debug('Certificate._invalidation_check({0})'.format(cert['name']))
        else:
            self.logger.debug('Certificate._invalidation_check()')

        to_be_cleared = False

        if cert and 'name' in cert:
            if 'cert' in cert and cert['cert'] and 'removed by' in cert['cert'].lower():
                if purge:
                    # skip entries which had been cleared before cert[cert] check is needed to cover corner cases
                    to_be_cleared = True

            elif 'expire_uts' in cert:
                # get expiry date from either dictionary or certificate
                to_be_cleared = self._expiredate_get(cert, timestamp, to_be_cleared)
            else:
                # this scneario should never been happen so lets be careful and not clear it
                to_be_cleared = False
        else:
            # entries without a cert-name can be to_be_cleared
            to_be_cleared = True

        if 'name' in cert:
            self.logger.debug('Certificate._invalidation_check({0}) ended with {1}'.format(cert['name'], to_be_cleared))
        else:
            self.logger.debug('Certificate._invalidation_check() ended with {0}'.format(to_be_cleared))

        return (to_be_cleared, cert)

    def _order_update(self, data_dic):
        """ update order based on ordername """
        self.logger.debug('Certificate._order_update({0})'.format(data_dic))
        try:
            self.dbstore.order_update(data_dic)
        except Exception as err_:
            self.logger.critical('acme2certifier database error in Certificate._order_update(): {0}'.format(err_))

    def _revocation_reason_check(self, reason):
        """ check reason """
        self.logger.debug('Certificate._revocation_reason_check({0})'.format(reason))

        # taken from https://tools.ietf.org/html/rfc5280#section-5.3.1
        allowed_reasons = {
            0: 'unspecified',
            1: 'keyCompromise',
            # 2: 'cACompromise',
            3: 'affiliationChanged',
            4: 'superseded',
            5: 'cessationOfOperation',
            6: 'certificateHold',
            # 8: 'removeFromCRL',
            # 9: 'privilegeWithdrawn',
            # 10: 'aACompromise'
        }

        result = allowed_reasons.get(reason, None)
        self.logger.debug('Certificate._revocation_reason_check() ended with {0}'.format(result))
        return result

    def _revocation_request_validate(self, account_name, payload):
        """ check revocaton request for consistency"""
        self.logger.debug('Certificate._revocation_request_validate({0})'.format(account_name))

        # set a value to avoid that we are returning none by accident
        code = 400
        error = None
        if 'reason' in payload:
            # check revocatoin reason if we get one
            rev_reason = self._revocation_reason_check(payload['reason'])
            # successful
            if not rev_reason:
                error = self.err_msg_dic['badrevocationreason']
        else:
            # set revocation reason to unspecified
            rev_reason = 'unspecified'

        if rev_reason:
            # check if the account issued the certificate and return the order name
            if 'certificate' in payload:
                order_name = self._account_check(account_name, payload['certificate'])
            else:
                order_name = None

            error = rev_reason
            if order_name:
                # check if the account holds the authorization for the identifiers
                auth_chk = self._authorization_check(order_name, payload['certificate'])
                if auth_chk:
                    # all good set code to 200
                    code = 200
                else:
                    error = self.err_msg_dic['unauthorized']

        self.logger.debug('Certificate._revocation_request_validate() ended with: {0}, {1}'.format(code, error))
        return (code, error)

    def _store_cert(self, certificate_name, certificate, raw, issue_uts=0, expire_uts=0, poll_identifier=None):
        """ get key for a specific account id """
        self.logger.debug('Certificate._store_cert({0})'.format(certificate_name))

        renewal_info_hex = self._renewal_info_get(certificate)

        data_dic = {'cert': certificate, 'name': certificate_name, 'cert_raw': raw, 'issue_uts': issue_uts, 'expire_uts': expire_uts, 'poll_identifier': poll_identifier, 'renewal_info': renewal_info_hex}
        try:
            cert_id = self.dbstore.certificate_add(data_dic)
        except Exception as err_:
            cert_id = None
            self.logger.critical('acme2certifier database error in Certificate._store_cert(): {0}'.format(err_))
        self.logger.debug('Certificate._store_cert({0}) ended'.format(cert_id))
        return cert_id

    def _store_cert_error(self, certificate_name, error, poll_identifier):
        """ get key for a specific account id """
        self.logger.debug('Certificate._store_cert_error({0})'.format(certificate_name))
        data_dic = {'error': error, 'name': certificate_name, 'poll_identifier': poll_identifier}
        try:
            cert_id = self.dbstore.certificate_add(data_dic)
        except Exception as err_:
            cert_id = None
            self.logger.critical('acme2certifier database error in Certificate._store_cert(): {0}'.format(err_))
        self.logger.debug('Certificate._store_cert_error({0}) ended'.format(cert_id))
        return cert_id

    def _tnauth_identifier_check(self, identifier_dic):
        """ check if we have an tnauthlist_identifier """
        self.logger.debug('Certificate._tnauth_identifier_check()')
        # check if we have a tnauthlist identifier
        tnauthlist_identifer_in = False
        if identifier_dic:
            for identifier in identifier_dic:
                if 'type' in identifier:
                    if identifier['type'].lower() == 'tnauthlist':
                        tnauthlist_identifer_in = True
        self.logger.debug('Certificate._tnauth_identifier_check() ended with: {0}'.format(tnauthlist_identifer_in))
        return tnauthlist_identifer_in

    def certlist_search(self, key, value, vlist=('name', 'csr', 'cert', 'order__name')):
        """ get certificate from database """
        self.logger.debug('Certificate.certlist_search({0}: {1})'.format(key, value))
        try:
            result = self.dbstore.certificates_search(key, value, vlist)
        except Exception as err_:
            self.logger.critical('acme2certifier database error in Certificate.certlist_search(): {0}'.format(err_))
            result = None
        return result

    def _cleanup(self, report_list, timestamp, purge):
        """ cleanup  """
        self.logger.debug('Certificate.cleanup({0},{1})'.format(timestamp, purge))
        if not purge:
            # we are just modifiying data
            for cert in report_list:
                data_dic = {
                    'name': cert['name'],
                    'expire_uts': cert['expire_uts'],
                    'issue_uts': cert['issue_uts'],
                    'cert': 'removed by certificates.cleanup() on {0} '.format(uts_to_date_utc(timestamp)),
                    'cert_raw': cert['cert_raw']
                }
                try:
                    self.dbstore.certificate_add(data_dic)
                except Exception as err_:
                    self.logger.critical('acme2certifier database error in Certificate.cleanup() add: {0}'.format(err_))
        else:
            # delete entries from certificates table
            for cert in report_list:
                try:
                    self.dbstore.certificate_delete('id', cert['id'])
                except Exception as err_:
                    self.logger.critical('acme2certifier database error in Certificate.cleanup() delete: {0}'.format(err_))

        self.logger.debug('Certificate.cleanup() ended')

    def cleanup(self, timestamp=None, purge=False):
        """ cleanup routine to shrink table-size """
        self.logger.debug('Certificate.cleanup({0},{1})'.format(timestamp, purge))

        field_list = ['id', 'name', 'expire_uts', 'issue_uts', 'cert', 'cert_raw', 'csr', 'created_at', 'order__id', 'order__name']

        # get expired certificates
        try:
            certificate_list = self.dbstore.certificates_search('expire_uts', timestamp, field_list, '<=')
        except Exception as err_:
            self.logger.critical('acme2certifier database error in Certificate.cleanup() search: {0}'.format(err_))
            certificate_list = []

        report_list = []
        for cert in certificate_list:
            (to_be_cleared, cert) = self._invalidation_check(cert, timestamp, purge)

            if to_be_cleared:
                report_list.append(cert)

        # cleanup
        self._cleanup(report_list, timestamp, purge)

        self.logger.debug('Certificate.cleanup() ended with: {0} certs'.format(len(report_list)))
        return (field_list, report_list)

    def _dates_update(self, cert):
        """ update issue and expiry date with date from certificate """
        self.logger.debug('Certificate._dates_update()')

        if 'issue_uts' in cert and 'expire_uts' in cert:
            if cert['issue_uts'] == 0 and cert['expire_uts'] == 0:
                if cert['cert_raw']:
                    (issue_uts, expire_uts) = cert_dates_get(self.logger, cert['cert_raw'])
                    if issue_uts or expire_uts:
                        self._store_cert(cert['name'], cert['cert'], cert['cert_raw'], issue_uts, expire_uts)

        self.logger.debug('Certificate._dates_update() ended')

    def dates_update(self):
        """ scan certificates and update issue/expiry date """
        self.logger.debug('Certificate.dates_update()')

        with Certificate(self.debug, None, self.logger) as certificate:
            cert_list = certificate.certlist_search('issue_uts', 0, vlist=('id', 'name', 'cert', 'cert_raw', 'issue_uts', 'expire_uts'))
            self.logger.debug('Got {0} certificates to be updated...'.format(len(cert_list)))
            for cert in cert_list:
                self._dates_update(cert)

        self.logger.debug('Certificate.dates_update() ended')

    def enroll_and_store(self, certificate_name, csr, order_name=None):
        """ check csr and trigger enrollment """
        self.logger.debug('Certificate.enroll_and_store({0},{1})'.format(certificate_name, order_name))

        # check csr against order
        csr_check_result = self._csr_check(certificate_name, csr)

        # only continue if self.csr_check returned True
        if csr_check_result:
            twrv = ThreadWithReturnValue(target=self._enroll_and_store, args=(certificate_name, csr, order_name))
            twrv.start()
            enroll_result = twrv.join(timeout=self.enrollment_timeout)
            if enroll_result:
                try:
                    (result, error, detail) = enroll_result
                except Exception as err_:
                    self.logger.error('acme2certifier database error in Certificate.enroll_and_store(): split of {0} failed with err: {1}'.format(enroll_result, err_))
                    result = None
                    error = self.err_msg_dic['serverinternal']
                    detail = 'unexpected enrollment result'
            else:
                result = None
                error = 'timeout'
                detail = 'timeout'
        else:
            result = None
            error = self.err_msg_dic['badcsr']
            detail = 'CSR validation failed'

        self.logger.debug('Certificate.enroll_and_store() ended with: {0}:{1}'.format(result, error))
        return (error, detail)

    def new_get(self, url):
        """ get request """
        certificate_name = string_sanitize(self.logger, url.replace('{0}{1}'.format(self.server_name, self.path_dic['cert_path']), ''))
        self.logger.debug('Certificate.new_get({0})'.format(certificate_name))
        # fetch certificate dictionary from DB
        certificate_dic = self._info(certificate_name, ['name', 'csr', 'cert', 'order__name', 'order__status_id'])
        response_dic = {}
        if 'order__status_id' in certificate_dic:
            if certificate_dic['order__status_id'] == 5:
                # oder status is valid - download certificate
                if 'cert' in certificate_dic and certificate_dic['cert']:
                    response_dic['code'] = 200
                    # filter certificate and decode it
                    response_dic['data'] = certificate_dic['cert']
                    response_dic['header'] = {}
                    response_dic['header']['Content-Type'] = 'application/pem-certificate-chain'
                else:
                    response_dic['code'] = 500
                    response_dic['data'] = self.err_msg_dic['serverinternal']
            elif certificate_dic['order__status_id'] == 4:
                # order status is processing - ratelimiting
                response_dic['header'] = {'Retry-After': '{0}'.format(self.retry_after)}
                response_dic['code'] = 403
                response_dic['data'] = self.err_msg_dic['ratelimited']
            else:
                response_dic['code'] = 403
                response_dic['data'] = self.err_msg_dic['ordernotready']
        else:
            response_dic['code'] = 500
            response_dic['data'] = self.err_msg_dic['serverinternal']

        self.logger.debug('Certificate.new_get({0}) ended'.format(response_dic['code']))

        return response_dic

    def new_post(self, content):
        """ post request """
        self.logger.debug('Certificate.new_post({0})')

        response_dic = {}
        # check message
        (code, message, detail, protected, _payload, _account_name) = self.message.check(content)
        if code == 200:
            if 'url' in protected:
                response_dic = self.new_get(protected['url'])
                if response_dic['code'] in (400, 403, 400, 500):
                    code = response_dic['code']
                    message = response_dic['data']
                    detail = None
            else:
                response_dic['code'] = code = 400
                # pylint: disable=w0612, w0622
                response_dic['data'] = self.err_msg_dic['malformed']
                detail = 'url missing in protected header'

        # prepare/enrich response
        status_dic = {'code': code, 'type': message, 'detail': detail}
        response_dic = self.message.prepare_response(response_dic, status_dic)

        # depending on the response the content of responsedic['data'] can be either string or dict
        # data will get serialzed
        if isinstance(response_dic['data'], dict):
            response_dic['data'] = json.dumps(response_dic['data'])

        # cover cornercase - not sure if we ever run into such situation
        if 'code' in response_dic:
            result = response_dic['code']
        else:
            result = 'no code found'

        self.logger.debug('Certificate.new_post() ended with: {0}'.format(result))
        return response_dic

    def revoke(self, content):
        """ revoke request """
        self.logger.debug('Certificate.revoke()')

        response_dic = {}
        # check message
        (code, message, detail, _protected, payload, account_name) = self.message.check(content)

        if code == 200:
            if 'certificate' in payload:
                (code, error) = self._revocation_request_validate(account_name, payload)
                if code == 200:
                    # revocation starts here
                    # revocation reason is stored in error variable
                    rev_date = uts_to_date_utc(uts_now())
                    with self.cahandler(self.debug, self.logger) as ca_handler:
                        (code, message, detail) = ca_handler.revoke(payload['certificate'], error, rev_date)
                else:
                    message = error
                    detail = None

            else:
                # message could not get decoded
                code = 400
                message = self.err_msg_dic['malformed']
                detail = 'certificate not found'

        # prepare/enrich response
        status_dic = {'code': code, 'type': message, 'detail': detail}
        response_dic = self.message.prepare_response(response_dic, status_dic)

        self.logger.debug('Certificate.revoke() ended with: {0}'.format(response_dic))
        return response_dic

    def poll(self, certificate_name, poll_identifier, csr, order_name):
        """ try to fetch a certificate from CA and store it into database """
        self.logger.debug('Certificate.poll({0}: {1})'.format(certificate_name, poll_identifier))

        with self.cahandler(self.debug, self.logger) as ca_handler:
            (error, certificate, certificate_raw, poll_identifier, rejected) = ca_handler.poll(certificate_name, poll_identifier, csr)
            if certificate:
                # get issuing and expiration date
                (issue_uts, expire_uts) = cert_dates_get(self.logger, certificate_raw)
                # update certificate record in database
                _result = self._store_cert(certificate_name, certificate, certificate_raw, issue_uts, expire_uts)
                # update order status to 5 (valid)
                try:
                    self.dbstore.order_update({'name': order_name, 'status': 'valid'})
                except Exception as err_:
                    self.logger.critical('acme2certifier database error in Certificate.poll(): {0}'.format(err_))
            else:
                # store error message for later analysis
                self._store_cert_error(certificate_name, error, poll_identifier)
                _result = None
                if rejected:
                    try:
                        self.dbstore.order_update({'name': order_name, 'status': 'invalid'})
                    except Exception as err_:
                        self.logger.critical('acme2certifier database error in Certificate.poll(): {0}'.format(err_))
        self.logger.debug('Certificate.poll({0}: {1})'.format(certificate_name, poll_identifier))
        return _result

    def store_csr(self, order_name, csr):
        """ store csr into database """
        self.logger.debug('Certificate.store_csr({0})'.format(order_name))
        certificate_name = generate_random_string(self.logger, 12)
        data_dic = {'order': order_name, 'csr': csr, 'name': certificate_name}
        try:
            self.dbstore.certificate_add(data_dic)
        except Exception as err_:
            self.logger.critical('Database error in Certificate.store_csr(): {0}'.format(err_))
        self.logger.debug('Certificate.store_csr() ended')
        return certificate_name