'''
Created on Oct 3, 2016

@author: Ramin
'''

import sys
from merkleTree import MerkleTree
from utilities import utilities
from verifier import verifier
from prover import prover

def printLeavesCount(lstLeaves):
    leavesCount = [len(x) for x in lstLeaves]
    print(leavesCount)

def aboutUs():
    print(utilities.BOLD + utilities.OKGREEN + '*****************************************************')
    print(utilities.BOLD + utilities.WARNING + '>>> Merkle Tree (Ver 1.2)\n>>> By Ramin Armanfar\n>>> Date: Oct 3, 2016\n>>> Last Update: Nov 20, 2016\nEmail: ramin.armanfar@gmail.com' + utilities.ENDC)
    print(utilities.BOLD + utilities.OKGREEN + '*****************************************************' + utilities.ENDC)

def getDataFromInput():
    dataBlockCount = 0
    while True:
        txtDataBlockCount = input(utilities.OKBLUE + 'Enter number of initial data blocks to create tree: ' + utilities.ENDC)
        try:
            dataBlockCount = int(txtDataBlockCount)
            break
        except:
            print(utilities.WARNING + '>>> Error: You must enter numeric value which represents the number of initial data blocks !!!' + utilities.ENDC)
            pass

    dataBlocks = []
    for i in range(dataBlockCount):
        db = input(utilities.OKBLUE + 'Enter number data block ' + str(i) + ' value: ' + utilities.ENDC)
        dataBlocks.append(db)
    return dataBlocks

def createTreeWithUserInput(mt):
    dataBlocks = getDataFromInput()

    #print(dir(mt))
    mt.createTree(dataBlocks, True)

def importDataFromFile():
    fn = input(utilities.OKBLUE + 'Enter number file name: ' + utilities.ENDC)
    fpt = open(fn, 'r')
    splitter = input(utilities.OKBLUE + 'Enter splitter character: ' + utilities.ENDC)
    dataBlocks = fpt.read()
    dataBlocks = dataBlocks.rstrip()
    dataBlocks = dataBlocks.split(splitter)
    return dataBlocks

def createTreeFromFile(mt):
    dataBlocks = importDataFromFile()
    print(utilities.OKGREEN + 'Imported data are: ' + utilities.ENDC)
    print(dataBlocks)
    #print(dir(mt))
    mt.createTree(dataBlocks, True)

def addOneDataBlock(mt):
        value = input(utilities.OKBLUE + 'Enter data block value to add to the tree: ' + utilities.ENDC)
        try:
            mt.addOneBlock(value)
            print(utilities.OKBLUE + '>>> Given value (', value, ') has been added to the tree successfully...' + utilities.ENDC)
        except:
            print(utilities.FAIL + '>>> Error: Tree object is not exist !!!')
            print('>>> You may need to create tree first...' + utilities.ENDC)

def addManyDataBlocksToTree(mt):
    if mt.root == None:
        yn = ''
        while True:
            yn = input(utilities.WARNING + '>>> Three has not been generated yet! do you want to create tree using given data blocks? (y/n)' + utilities.ENDC)
            if yn == 'y' or yn == 'n' or yn == 'Y' or yn == 'N':
                break
        if yn =='y' or yn == 'Y':
            dataBlocks = importDataFromFile()
            print(utilities.OKBLUE + 'Imported data are: ' + utilities.ENDC)
            print(dataBlocks)
            mt.createTree(dataBlocks, True)
    else:
        dataBlocks = getDataFromInput()
        mt.addManyDataBlocks(dataBlocks)

def addManyDataBlocksToTreeFromFile(mt):
    if mt.root == None:
        yn = ''
        while True:
            yn = input(utilities.WARNING + '>>> Three has not been generated yet! do you want to create tree using given data blocks? (y/n)' + utilities.ENDC)
            if yn == 'y' or yn == 'n' or yn == 'Y' or yn == 'N':
                break
        if yn =='y' or yn == 'Y':
            dataBlocks = importDataFromFile()
            print(utilities.OKBLUE + 'Imported data are: ' + utilities.ENDC)
            print(dataBlocks)
            mt.createTree(dataBlocks, True)
    else:
        dataBlocks = importDataFromFile()
        print('Imported data are: ')
        print(dataBlocks)
        mt.addManyDataBlocks(dataBlocks)

def main(argv):
    mt = MerkleTree()
    aboutUs()
    menuItem = '-'
    #utilities.clearScreen()

    while True:
        print('\n' + utilities.BOLD + utilities.OKGREEN + '*************** Merkle-Tree Main Menu ***************' + utilities.ENDC)
        print(utilities.OKBLUE + '1) Create Merkle-Tree')
        print('2) Add new data block(s)')
        print('3) Show a path')
        print('4) Graph Tree')
        print('5) Proof of path')
        print('6) Proof of consistency')
        print('7) About Us')
        print('0) Exit' + utilities.ENDC)
        menuItem = input(utilities.OKGREEN + 'Choose an item (0 - 7): ' + utilities.ENDC)
        if menuItem == '0': ### Exit the program
            while True:
                yn = input(utilities.WARNING + 'Exit Program, Are you sure? (y/n): ' + utilities.ENDC)
                if yn == 'y' or yn == 'n' or yn == 'Y' or yn == 'N': break
            if yn == 'y' or yn == 'Y':
                aboutUs()
                print(utilities.OKBLUE + utilities.BOLD + 'Thank you for using the application...' + utilities.ENDC)
                break

        elif menuItem == '1': ### Create tree by giving number of specific values from the user
            while True:
                print(utilities.BOLD + utilities.OKGREEN + '*************** Create Tree Sub-Menu ***************' + utilities.ENDC)
                print(utilities.OKBLUE + '1) Create tree with user input')
                print('2) Create tree with imported data from a file')
                print('0) Return to main menu' + utilities.ENDC)
                subMenuItem = input(utilities.OKGREEN + 'Choose one of items (0, 1, or 2): ' + utilities.ENDC)
                if subMenuItem == '0':
                    break
                elif subMenuItem == '1':
                    if mt.root != None:
                        yn = ''
                        while True:
                            yn = input(utilities.WARNING + 'Warning: Tree has already been created. Do you want to recreate it? (y/n): ' + utilities.ENDC)
                            if yn == 'y' or yn == 'n' or yn == 'Y' or yn == 'N':
                                break
                        if yn =='y' or yn == 'Y':
                            createTreeWithUserInput(mt)
                            print(utilities.OKBLUE + '>>> The tree has been recreated successfully...' + utilities.ENDC)
                    else:
                        createTreeWithUserInput(mt)
                        print(utilities.OKBLUE + '>>> The tree has been created successfully...' + utilities.ENDC)

                elif subMenuItem == '2':
                    if mt.root != None:
                        yn = ''
                        while True:
                            yn = input(utilities.WARNING + 'Warning: Tree has already been created. Do you want to recreate it? (y/n): ' + utilities.ENDC)
                            if yn == 'y' or yn == 'n' or yn == 'Y' or yn == 'N':
                                break
                        if yn =='y' or yn == 'Y':
                            createTreeFromFile(mt)
                            print(utilities.OKBLUE + '>>> The tree has been recreated successfully...' + utilities.ENDC)
                    else:
                        createTreeFromFile(mt)
                        print(utilities.OKBLUE + '>>> The tree has been created successfully...' + utilities.ENDC)

                else:
                    print(utilities.FAIL + '>>> Error: You are allowed to enter numbers (1 - 3) to choose sub menu items !!!' + utilities.ENDC)

        elif menuItem == '2': ### Adding new data block(s) to the tree
            while True:
                print(utilities.BOLD + utilities.OKGREEN + '*************** Add Data Block(s) to the Tree Sub-Menu ***************' + utilities.ENDC)
                print(utilities.OKBLUE + '1) Add a data block')
                print('2) Add batch data blocks with user input')
                print('3) Add batch data blocks with importing data from a file')
                print('0) Return to main menu' + utilities.ENDC)
                subMenuItem = input(utilities.OKGREEN + 'Choose one of items (0, 1, 2, or 3): ' + utilities.ENDC)
                if subMenuItem == '0':
                    break
                elif subMenuItem == '1':
                    addOneDataBlock(mt)
                elif subMenuItem == '2':
                    addManyDataBlocksToTree(mt)
                elif subMenuItem == '3':
                    addManyDataBlocksToTreeFromFile(mt)
                else:
                    print(utilities.FAIL + '>>> Error: You are allowed to enter numbers (1 - 4) to choose sub menu items !!!' + utilities.ENDC)

        ###################### Show information of an specific path in the tree ######################
        elif menuItem == '3':
            if mt.root == None:
                print(utilities.FAIL + '>>> Error: The tree has not beet created yet !!!')
                print('>>> Please create tree first.' + utilities.ENDC)
            else:
                numberOfDataBlocks = len(mt.getDataBlocks())
                strPathIndex = '-'
                while strPathIndex != '-1':
                    strPathIndex = input(utilities.OKGREEN + 'Enter path index (0 - ' + str(numberOfDataBlocks - 1) + ') to show or enter (-1) to return main menu: ' + utilities.ENDC)
                    pathIndex = int(strPathIndex)
                    layerIndex, leafIndex = mt.getDataIndices(pathIndex)
                    if layerIndex == -1 or leafIndex == -1:
                        print(utilities.FAIL + '>>> Error: Given path index (' + strPathIndex + ') is out of range !!!')
                        print('>>> There is/are (' + str(numberOfDataBlocks) + ') data block(s) in the tree. You can enter number between (0 - ' + str(numberOfDataBlocks - 1) + ').' + utilities.ENDC)
                    else:
                        print(utilities.OKBLUE + '>>> Show path chain...' + utilities.ENDC)
                        mt.printPath(layerIndex, leafIndex)
                        break

        ###################### Graph Tree ######################
        elif menuItem == '4':
            utilities.graphTree(mt, 'Display MHT Graph')

        ###################### Proof of a path ######################
        elif menuItem == '5':
            if mt.root == None:
                print(utilities.FAIL + '>>> Error: The tree has not beet created yet !!!')
                print('>>> Please create tree first.' + utilities.ENDC)
            elif len(mt.getDataBlocks()) <= 1:
                print(utilities.FAIL + '>>> Error: The tree has only one node !!!')
                print('>>> Proof of path needs at least two nodes.' + utilities.ENDC)
            else:
                numberOfDataBlocks = len(mt.getDataBlocks())
                strPathIndex = '-'
                while strPathIndex != '0':
                    strPathIndex = input(utilities.OKGREEN + 'Enter path index (1 - ' + str(numberOfDataBlocks) + ') to show or enter (0) to return main menu: ' + utilities.ENDC)
                    if strPathIndex == '0': break
                    pathIndex = int(strPathIndex) - 1
                    layerIndex, leafIndex = mt.getDataIndices(pathIndex)
                    if layerIndex == -1 or leafIndex == -1:
                        print(utilities.FAIL + '>>> Error: Given path index (' + strPathIndex + ') is out of range !!!')
                        print('>>> There is/are (' + str(numberOfDataBlocks) + ') data block(s) in the tree. You can enter number between (1 - ' + str(numberOfDataBlocks) + ').' + utilities.ENDC)
                    else:
                        break

                print(utilities.OKBLUE + '>>> Proving leaf node (' + mt.lstDataBlocks[layerIndex][leafIndex] + ')...' + utilities.ENDC)
                lstProofPathChain = prover.proofPath(mt, layerIndex, leafIndex)
                lstVerifiedPathChain, proved = verifier.verifyPath(mt, layerIndex, leafIndex, lstProofPathChain)

                #lstProofOfPath, proved = mt.proofOfPath(layerIndex, leafIndex)
                i = 0
                for item in lstVerifiedPathChain:
                    i += 1
                    print(i, ')', str(item))

                if proved:
                    print(utilities.BOLD + utilities.WARNING + '>>> Path chain has been proved...' + utilities.ENDC)
                else:
                    print(utilities.BOLD + utilities.WARNING + '>>> Path chain has NOT been proved !!!' + utilities.ENDC)

                utilities.graphTree(mt, 'Proof Of Path Index ' + strPathIndex, lstVerifiedPathChain)
        ###################### Proof of consistency ######################
        elif menuItem == '6':
            if mt.root == None:
                print(utilities.FAIL + '>>> Error: The tree has not beet created yet !!!')
                print('>>> Please create tree first.' + utilities.ENDC)
            else:
                numberOfDataBlocks = len(mt.getDataBlocks())
                strPathIndex = '-'
                while strPathIndex != '0':
                    strPathIndex = input(utilities.OKGREEN + 'Enter path index (1 - ' + str(numberOfDataBlocks) + ') to show or enter (0) to return main menu: ' + utilities.ENDC)
                    if strPathIndex == '0': break
                    pathIndex = int(strPathIndex) - 1
                    layerIndex, leafIndex = mt.getDataIndices(pathIndex)
                    if layerIndex == -1 or leafIndex == -1:
                        print(utilities.FAIL + '>>> Error: Given path index (' + strPathIndex + ') is out of range !!!')
                        print('>>> There is/are (' + str(numberOfDataBlocks) + ') data block(s) in the tree. You can enter number between ( - ' + str(numberOfDataBlocks) + ').' + utilities.ENDC)
                    else:
                        print(utilities.OKBLUE + '>>> Consistency Proof List...' + utilities.ENDC)
                        lstConsistencyProof = prover.proofConsistency(mt, pathIndex + 1, 0, numberOfDataBlocks, True)
                        verified = verifier.verifyConsistency(mt, lstConsistencyProof, lstConsistencyProof)

                        lstNodes = utilities.getListColumn(lstConsistencyProof, 0)
                        lstLevels = utilities.getListColumn(lstConsistencyProof, 1)
                        for r in lstConsistencyProof:
                            print(lstConsistencyProof.index(r) + 1, ')', str(r[0]), ', Level:', r[1])
                        utilities.graphTree(mt, 'Consistency Proof (Leaf Index = '+ strPathIndex + ')', lstNodes)
                        print(utilities.OKBLUE + '>>> Verifying consistency Proof List...' + utilities.ENDC)
                        break
        ###################### About the project ######################
        elif menuItem == '7':
            aboutUs()

    return 0

    #print('Guaranteed:\n{}\n'.format(', '.join(sorted(hashlib.algorithms_guaranteed))))
    #print('Available:\n{}'.format(', '.join(sorted(hashlib.algorithms_available))))

if __name__ == '__main__':
    main(sys.argv)
    exit(0)


import sys
_module = sys.modules[__name__]
del sys
conf = _module
mnist = _module
mnist_with_meterlogger = _module
mnist_with_visdom = _module
setup = _module
test_datasets = _module
test_meters = _module
test_transforms = _module
torchnet = _module
dataset = _module
batchdataset = _module
concatdataset = _module
dataset = _module
listdataset = _module
resampledataset = _module
shuffledataset = _module
splitdataset = _module
tensordataset = _module
transformdataset = _module
engine = _module
engine = _module
logger = _module
meterlogger = _module
visdomlogger = _module
meter = _module
apmeter = _module
aucmeter = _module
averagevaluemeter = _module
classerrormeter = _module
confusionmeter = _module
mapmeter = _module
movingaveragevaluemeter = _module
msemeter = _module
timemeter = _module
transform = _module
utils = _module
multitaskdataloader = _module
resultswriter = _module
table = _module

from _paritybench_helpers import _mock_config, patch_functional
from unittest.mock import mock_open, MagicMock
from torch.autograd import Function
from torch.nn import Module
import abc, collections, copy, enum, functools, inspect, itertools, logging, math, matplotlib, numbers, numpy, pandas, queue, random, re, scipy, sklearn, string, tensorflow, time, torch, torchaudio, torchtext, torchvision, types, typing, uuid, warnings
import numpy as np
from torch import Tensor
patch_functional()
open = mock_open()
yaml = logging = sys = argparse = MagicMock()
ArgumentParser = argparse.ArgumentParser
_global_config = args = argv = cfg = config = params = _mock_config()
argparse.ArgumentParser.return_value.parse_args.return_value = _global_config
yaml.load.return_value = _global_config
sys.argv = _global_config
__version__ = '1.0.0'
xrange = range
wraps = functools.wraps

import torch

import torch.optim

from torchvision.datasets.mnist import MNIST

from torch.autograd import Variable

import torch.nn.functional as F

from torch.nn.init import kaiming_normal

import numpy as np

import math

from torch.utils.data import DataLoader

import numbers

from itertools import islice

from itertools import chain

from itertools import repeat

import torch.utils.data


"""
String formatting provides a more powerful way to embed non-strings within strings. String formatting uses a string's format method to substitute a number of arguments in the string.
"""

nums = [13, 21, 55]
msg = "Numbers: {0} {1} {2}". format(nums[0], nums[1], nums[2])
print(msg)

# Each argument of the format function is placed in the string at the corresponding position, which is determined using the curly braces { }.

# String formatting can also be done with named arguments.

a = "{x}, {y}".format(x=5, y=12)
print(a)


import os
import json
import redis
import time
from datetime import datetime

import usermodule

# Get variables set by deployment and setup redis connection
REDIS_HOST = os.getenv("REDIS_HOST")
REDIS_PORT = int(os.getenv("REDIS_PORT"))
REDIS_INPUT_KEY = os.getenv("REDIS_INPUT_KEY")
REDIS_OUTPUT_KEY = os.getenv("REDIS_OUTPUT_KEY")
r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0, decode_responses=True)

# Define interval between calls, in seconds
STEP = 5

class Context:
    """
    Context object used by handler function

    Attributes:
    host: Hostname of the server running Redis.
    port: Port where the Redis server is listening.
    input_key: Input key used to read monitoring data from Redis.
    output_key: Output key used to store metrics on Redis.
    function_getmtime: Timestamp of the last update to your module's Python
                       file.
    last_execution: Timestamp of last execution of your serverless function and
                    result storage on Redis.
    env: A JSON-encodable dictionary that persists between calls to the your
         serverless function. This variable can be used to persist small amounts
         of user data (context environment) between executions
    """

    def __init__(self):
        self.host = REDIS_HOST
        self.port = REDIS_PORT
        self.input_key = REDIS_INPUT_KEY
        self.output_ket = REDIS_OUTPUT_KEY
        self.last_execution = ""
        self.env = {}

        # Getting last modified time
        tmstmp = os.path.getmtime("usermodule.py")
        self.function_getmtime = datetime.fromtimestamp(tmstmp)

    def update_execution(self):
        self.last_execution = datetime.now()

def main():
    ctx = Context()
    last_data = None
    data = None
    while(1):
        # Read data from redis
        r_dict = r.get(REDIS_INPUT_KEY)
        r_dict = json.loads(r_dict)

        last_data = data
        data = r_dict

        # Call handler to update the differences, if any
        if (last_data != data):
            output = usermodule.handler(data, ctx)
            r.set(REDIS_OUTPUT_KEY, json.dumps(output))
            ctx.update_execution()
        time.sleep(STEP)

# Write back on redis
if __name__ == "__main__":
    main()


# -*- coding: utf-8 -*-
"""
Created on Tue Jan  3 13:44:21 2017

@author: Andrew
"""

import numpy as np
from numpy import newaxis
from k_means_auxiliary import dist, Inf, compute_new_clusters

def classic_k_means(data, k, steps = Inf, report = False):
    n, d = data.shape
    best = np.zeros(n, int)
    old_best = np.ones(n, int) * k  #nasty trick (see compute_new_clusters)
    clusters = data[:k].copy()
    cluster_sizes = np.zeros(k, int)

    stop = False
    it_num = 0
    dist.count = 0
    while (not stop) and it_num < steps:
        it_num += 1

        # assignment step
        for x in range(n):
            best[x] = np.argmin([dist(data[x], c) for c in clusters])

        #center update step
        clusters, cluster_sizes = \
            compute_new_clusters(data, clusters ,old_best, best, cluster_sizes)
        if np.all(best == old_best):
            stop = True
        best, old_best = old_best, best

    if report:
        print("classic   : iter = %i, dist. calcs = %i, "
              % (it_num, dist.count), end = "")
    return (clusters, best)


"""Library for parsing metadata files from Bruker scope. Modified from Deisseroth lab code"""
import os
import json
import logging
import pathlib
import pprint

from xml.etree import ElementTree
logger = logging.getLogger(__name__)

class MetadataError(Exception):
    """Error while extracting metadata."""

class MetadataWarning(Warning):
    """Warning while extracting metadata."""

def read_main_xml(fname):
    '''

    '''

    data = {
        'layout': {
            'sequences': None,
            'frames_per_sequence': None,
            'samples_per_pixel': None
        },
        'size': {
            'frames': None,
            'channels': None,
            'z_planes': None,
            'y_px': None,
            'x_px': None,
        },
        'pixel_size': None,
        'laser_power': {},
        'frame_period': None,
        'line_period': None,
        'optical_zoom': None,
        'pmts': {},
        'preamp_filter': None,
        'preamp_offsets': {},
        'scan_mode': None,
        'bit_depth': None,
        'frame_times': []
        }

    if fname is None:
        return data

    mdata_root = ElementTree.parse(fname).getroot()

    def state_value(key, type_fn=str):
        element = mdata_root.find(f'.//PVStateValue[@key="{key}"]')
        value = element.attrib['value']
        return type_fn(value)

    def indexed_value(key, index, type_fn=None, required=True, description=False):
        element = mdata_root.find(f'.//PVStateValue[@key="{key}"]/IndexedValue[@index="{index}"]')
        if element is None:
            if required:
                raise MetadataError('Could not find required key:index of %s:%s' % (key, index))
            return None

        value = element.attrib['value']

        if description:
            return type_fn(value), element.attrib['description']
        else:
            return type_fn(value)

    data['scan_mode'] = state_value('activeMode',str)
    data['bit_depth'] = state_value('bitDepth', int)

    sequences = mdata_root.findall('Sequence')

    data['layout']['sequences'] = len(sequences)

    # Frames/sequence should be constant, except for perhaps the last frame.
    data['layout']['frames_per_sequence'] = len(sequences[0].findall('Frame'))

    if data['layout']['sequences'] == 1:
        data['size']['frames'] = data['layout']['frames_per_sequence']
        data['size']['z_planes'] = 1
    else:
        # If the last sequence has a different number of frames, ignore it.
        num_frames_last_sequence = len(sequences[-1].findall('Frame'))
        if data['layout']['frames_per_sequence'] != num_frames_last_sequence:
            logging.warning('Skipping final stack because it was found with fewer z-planes (%d, expected: %d).',
                            num_frames_last_sequence, data['layout']['frames_per_sequence'])
            data['layout']['sequences'] -= 1
        data['size']['frames'] = data['layout']['sequences']
        data['size']['z_planes'] = data['layout']['frames_per_sequence']

    data['size']['channels'] = len(mdata_root.find('Sequence/Frame').findall('File'))
    data['size']['y_px'] = state_value('linesPerFrame', int)
    data['size']['x_pix'] = state_value('pixelsPerLine', int)

    data['layout']['samples_per_pixel'] = state_value('samplesPerPixel', int)

    data['pixel_size'] = {
             'x': indexed_value('micronsPerPixel', 'XAxis', float),
             'y': indexed_value('micronsPerPixel', 'YAxis', float),
             'z': indexed_value('micronsPerPixel', 'ZAxis', float),
             }

    for i in range(3):
        _elem = indexed_value('laserPower', i, float, required=True, description=True)
        data['laser_power'][_elem[1]]=_elem[0]

    data['frame_period'] = state_value('framePeriod', float)
    data['line_period'] = state_value('scanLinePeriod', float)

    data['optical_zoom'] = state_value('opticalZoom', float)

    data['pmts'] = {0: indexed_value('pmtGain', 0, float),
           1: indexed_value('pmtGain', 1, float)}

    data['preamp_filter'] = state_value('preampFilter')
    preamp_subindex = mdata_root.find('.//PVStateValue[@key="preampOffset"]/SubindexedValues[@index="0"]')
    data['preamp_offsets'] = {0: preamp_subindex.find('.//SubindexedValue[@subindex="0"]').attrib['value'],
                              1: preamp_subindex.find('.//SubindexedValue[@subindex="1"]').attrib['value']}

    # get all frame times
    for seq in sequences:
        _frame_times = []
        frames = seq.findall('Frame')
        for frame in frames:
            _frame_times.append(float(frame.attrib['relativeTime']))
        data['frame_times'].append(_frame_times)

    # if last sequence is funky
    num_frames_last_sequence = len(sequences[-1].findall('Frame'))
    if data['layout']['frames_per_sequence'] != num_frames_last_sequence:
        _ = data['frame_times'].pop()

    return data

def read_vr_xml(fname):
    """_summary_

    Args:
        fname (_type_): _description_
    """
    data = {
        'channels': {},
        'acquisition_rate': None,
        'acquisition_time': None,
        'num_samples_acquired': None,
        'trigger': None,
        'trigger_count': None
    }

    if fname is None:
        return data

    voltage_root = ElementTree.parse(fname).getroot()

    for signal in voltage_root.findall('Experiment/SignalList/VRecSignal'):
        channel_num = int(signal.find('Channel').text)
        channel_name = signal.find('Name').text
        enabled = signal.find('Enabled').text == 'true'
        data['channels'][channel_num] = {'name': channel_name, 'enabled': enabled}

    data['acquisition_rate'] = int(voltage_root.find('Experiment/Rate').text) # Hz
    data['acquisition_time'] = int(voltage_root.find('Experiment/AcquisitionTime').text) # ms
    data['num_samples_acquired'] = int(voltage_root.find('SamplesAcquired').text)
    data['trigger'] = voltage_root.find('Experiment/Trigger').text
    data['trigger_count'] = int(voltage_root.find('Experiment/TriggerCount').text)

    return data

def read_mp_xml(fname):
    """

    Args:
        fname (_type_): _description_
    """
    data = {
        'iterations': None,
        'iteration_delay': None,
        'repetitions': None,
        'uncaging_laser': None,
        'trigger': None,
        'trigger_freq': None,
        'trigger_count': None,
        'uncaging_power': None,
        'custom_laser_power': None,
        'initial_delay': None,
        'inter_point_delay': None,
        'duration': None,
        'spiral_revolutions': None,
        'indices': None,
        'points_list': None,

    }

    if fname is None:
        return data

    markpoints_root = ElementTree.parse(fname).getroot()

    data['iterations'] = int(markpoints_root.attrib['Iterations'])
    data['iteration_delay'] = float(markpoints_root.attrib['IterationDelay'])

    mpe = markpoints_root.find('PVMarkPointElement').attrib
    data['repetitions'] = int(mpe['Repetitions'])
    data['uncaging_laser'] = mpe['UncagingLaser']
    data['trigger'] = mpe['TriggerSelection']
    data['trigger_freq'] = mpe['TriggerFrequency']
    data['trigger_count'] = int(mpe['TriggerCount'])
    data['uncaging_power'] = int(mpe['UncagingLaserPower'])
    try:
        data['custom_laser_power'] = [float(p)/16384.*1000 for p in mpe['CustomLaserPower'].split(',')]
    except:
        pass

    gpe = markpoints_root.find('PVMarkPointElement/PVGalvoPointElement').attrib
    data['initial_delay'] = float(gpe['InitialDelay'])
    data['inter_point_delay'] = float(gpe['InterPointDelay'])
    data['duration'] = float(gpe['Duration'])
    data['spiral_revolutions'] = float(gpe['SpiralRevolutions'])
    data['indices'] = gpe['Indices']

    data['points_list'] = [p.attrib for p in markpoints_root.findall('PVMarkPointElement/PVGalvoPointElement/Point')]

    for d in data['points_list']:
        for key, val in d.items():
            if key == 'IsSpiral':
                d[key] = bool(val)
            else:
                d[key] = float(val)

    return data

def read(basename_input, output_fname=None):
    """Read in metdata from XML files."""
    fname_xml = basename_input.with_suffix('.xml')
    fname_vr_xml = pathlib.Path(str(basename_input) + '_Cycle00001_VoltageRecording_001').with_suffix('.xml')
    fname_mp_xml = pathlib.Path(str(basename_input) + '_Cycle00001_MarkPoints').with_suffix('.xml')

    if not os.path.exists(fname_xml):
        raise MetadataError("metadata file %s does not exist"  % str(fname_xml))

    logger.info('Extracting metadata from xml files:\n%s', fname_xml)
    scan_data = read_main_xml(fname_xml)

    if not os.path.exists(fname_vr_xml):
        vr_data = read_vr_xml(None)
        MetadataWarning("voltage recording file %s does not exist, skipping" % fname_vr_xml)
    else:
        logger.info('\n%s' % fname_vr_xml)
        vr_data = read_vr_xml(fname_vr_xml)

    if not os.path.exists(fname_mp_xml):
        mp_data = read_mp_xml(None)
        MetadataWarning("mark points file %s does not exist, skipping" % fname_mp_xml)
    else:
        mp_data = read_mp_xml(fname_mp_xml)

    metadata = {
        **scan_data,
        'voltage_recording': vr_data,
        'mark_points': mp_data,
        }

    if output_fname is not None:
        with open(output_fname, 'w') as fout:
            json.dump(metadata, fout, indent=4, sort_keys=True)

        logger.info('Metadata written to: %s\n', output_fname)

    return metadata


import argparse
import xml.etree.ElementTree as ET
from cvss import CVSS3

csvHeaders = ['CVSS Score', 'IP', 'FQDN', 'OS', 'Port', 'Vulnerability', 'Description', 'Proof', 'Solution', 'See Also', 'CVE', 'CVSS_Vector', 'cvss3_base_score']
nessusFields = ['cvss_base_score', 'host-ip', 'host-fqdn', 'operating-system', 'port', 'plugin_name', 'description', 'plugin_output', 'solution', 'see_also', 'cve', 'cvss_vector', 'cvss3_base_score']
FailList = []
ActionPointList = []
# Clean values from nessus report
def getValue(rawValue):
	cleanValue = rawValue.replace('\n', ' ').strip(' ')
	if len(cleanValue) > 32000:
		cleanValue = cleanValue[:32000] + ' [Text Cut Due To Length]'
	return cleanValue

# Helper function for handleReport()
def getKey(rawKey):
	return csvHeaders[nessusFields.index(rawKey)]

# Handle a single report item
def handleReport(report):
	findings = []

	reportHost = dict.fromkeys(csvHeaders, '')
	for item in report:
		flag = False
		if item.tag == 'HostProperties':
			for tag in (tag for tag in item if tag.attrib['name'] in nessusFields):
				reportHost[getKey(tag.attrib['name'])] = getValue(tag.text)
		if item.tag == 'ReportItem':
			reportRow = dict(reportHost)
			reportRow['Port'] = item.attrib['port']
			reportRow['Vulnerability'] = item.attrib['pluginName']
			for tag in (tag for tag in item if tag.tag in nessusFields):
				reportRow[getKey(tag.tag)] = getValue(tag.text)
				if tag.tag == 'cvss3_base_score':
					if float(tag.text) > 6.9:
						FailList.append(reportRow['Vulnerability'] + "\t\t\tScore: "+ tag.text + "\t\tHost: " + reportRow['IP'])
					if float(tag.text) < 6.9 and float(tag.text) > 4.0:
						ActionPointList.append(reportRow['Vulnerability']  + "\t\t\tScore: "+ tag.text + "\t\tHost: " + reportRow['IP'])
					flag = True
				if tag.tag == 'cvss_vector' and flag == False:
					item1 = ET.SubElement(item, 'cvss3_base_score')
					item1.text=str(CVSSConvert(tag.text))

					if CVSSConvert(tag.text) > 6.9:
						FailList.append(reportRow['Vulnerability'] + "\t\t\tScore: "+ str(CVSSConvert(tag.text)) + "\t\tHost: " + reportRow['IP'])
					if CVSSConvert(tag.text) < 6.9 and CVSSConvert(tag.text) > 4.0:
						ActionPointList.append(reportRow['Vulnerability']  + "\t\t\tScore: "+ str(CVSSConvert(tag.text)) + "\t\tHost: " + reportRow['IP'])

			# Clean up - Mike G
			if reportRow['CVSS Score'] != "":
			   findings.append(reportRow)
	return findings

def CVSSConvert(cssvector):
	convertedVector = cssvector.replace("CVSS2#","CVSS:3.0/")
	convertedVector = convertedVector.replace("AV:L","AV:N")
	convertedVector = convertedVector.replace("AV:A","AV:N")
	convertedVector = convertedVector.replace("AC:M","AC:L")
	convertedVector = convertedVector.replace("AC:H","AC:L")
	convertedVector = convertedVector.replace("Au:S","PR:N")
	convertedVector = convertedVector.replace("Au:M","PR:N")
	convertedVector = convertedVector.replace("Au:N","PR:N")
	convertedVector = convertedVector.replace(":P",":L")
	convertedVector = convertedVector.replace(":C",":H")
	convertedVector = convertedVector + "/UI:N/E:F/RC:C/S:U"

	c = CVSS3(convertedVector)
	return c.scores()[0]

# Get files
def handleArgs():
	aparser = argparse.ArgumentParser(description='CEPLUS Nessus Interpreter.', usage="\npython3 CE_CVSS_Converter.py input.nessus")
	aparser.add_argument('nessus_xml_files', type=str, nargs='+', help="nessus xml file to parse")
	args = aparser.parse_args()
	return args.nessus_xml_files

if __name__ == '__main__':
	for nessusScan in handleArgs():
		try:
			scanfile = ET.parse(nessusScan)
		except IOError:
			print("Can't find file: " + nessusScan)
			exit()
		xmlRoot = scanfile.getroot()
		for report in xmlRoot.findall('./Report/ReportHost'):
			findings = handleReport(report)
			# print(findings)
	scanfile.write('CVSSv3_nessusScan')

	print("\033[1;31;40m--------------------FAIL---------------------")
	for item in FailList:
		print(item)
	print("\n\n\n\033[1;33;40m-----------------ACTIONPOINT-----------------")
	for item in ActionPointList:
		print(item)


from collections import deque
import math

"""Traffic node: a small, standard 4-way intersection"""
class Intersection:
    N_BRANCHES = 4
    # time to clear intersection, from the distance of in and out lane
    CLEAR_TIMES = [2, 3, 2, 1]

    def __init__(self):
        # store the in and out connections
        self.in_directions = {}   # map inlet node to its direction
        self.out_directions = {}  # map outlet node to its direction
        self.out_lanes = {}       # map outlet node to the corresponding lane

        # keep track of the car within this intersection
        self.car = None
        self.clear_time = math.inf
        self.cur_out_lane = None

        # queue of car waiting to enter
        self.wait_queue = deque()
        self.waiting_cars = set()

        # viz stuff
        self.vizSquare = None

    def set_in_lane(self, direction, lane):
        self.in_directions[lane.prev_node] = direction

    def set_out_lane(self, direction, lane):
        self.out_directions[lane.next_node] = direction
        self.out_lanes[lane.next_node] = lane

    def enter(self, prev_node, car):
        if self.car is not None:
            # the car has to wait because intersection is occupied
            # add the car to the wait queue, if it's not already in the queue
            if car not in self.waiting_cars:
                self.waiting_cars.add(car)
                self.wait_queue.append(car)
            return False
        if self.wait_queue and self.wait_queue[0] != car:
            return False
        if self.wait_queue:
            self.wait_queue.popleft()
            self.waiting_cars.remove(car)
        self.car = car
        next_node = car.select_next_node(self)
        dir_diff = self.out_directions[next_node].value - self.in_directions[prev_node].value
        self.clear_time = Intersection.CLEAR_TIMES[dir_diff % Intersection.N_BRANCHES]
        self.cur_out_lane = self.out_lanes[next_node]
        return True

    def update(self):
        if self.clear_time <= 0 and self.cur_out_lane.enter(self.car):
            # if car has been in intersection for long enough,
            # forward it to the next node
            self.car = None
            self.clear_time = math.inf
        else:
            self.clear_time -= 1

    def __str__(self):
        if self.car:
            return "%3d (%3d)" % (self.car.car_id, self.clear_time)
        else:
            return " (empty) "


"""
Premier programme écrit en Python le 19.02.2021
    D'après la video de tuto APPRENDRE PYTHON:
        https://www.youtube.com/watch?v=oUJolR5bX6g&t=49s
"""

def afficher_nom_age(n,a):
    print("""
        Tu t'appelles %s et tu as %s ans
            Dans un an tu auras %s ans
        """ % (n, a, int(a)+1))

def demander_age():
    age = 0
    while age == 0:
        try:
            age = int(input("age? "))
        except:
            print("recommence avec nombre stp")
    return age

def demander_nom():
    nom = ""
    while nom == "":
        nom = input("nom? ")
    return nom

j: float = 0

def pairs():
    for i in range(0, 11):
        global j
        j = i/2
        if j.is_integer():
            print(f"{i} est pair")
        else:
            print("%s est impair" % i)

def divisible(n:int,d:int):
    return not d==0 and (n/d).is_integer()

def is_premier(p):
    Diviseurs = [2, 3, 5, 7]
    i = 0
    while (i<4):
        if (p/Diviseurs[i]).is_integer():
            return False
        else:
             i = i+1
    return True

def premiers100():

    liste = []
    for i in range(101):
        if is_premier(i):
            liste.append(i)
    print(liste)

#nom_str = demander_nom()
#age_int = demander_age()

print()
#afficher_nom_age(nom_str,str(age_int))
# pairs()
premiers100()


import numpy as np
from scipy.interpolate import interp1d
from scipy.signal import savgol_filter

def interpolation_one_d(motion_indices):
    x = np.arange(0, motion_indices.size)
    f = interp1d(x, motion_indices, kind='cubic')
    x_new = np.arange(0, motion_indices.size - 1, 0.1)
    y_new = f(x_new)

    return x_new, y_new

def compute_velocity(x, y):
    x = x[0:-1] + np.diff(x) / 2
    y = set_savgol(np.diff(y) / x[1], 4)
    return x, y

def compute_acceleration(x, y):
    x, y = compute_velocity(x, y)
    x = x[0:-1] + np.diff(x) / 2
    y = set_savgol(np.diff(y) / x[1], 4)
    return x, y

def extract_features():
    pass

class BackgroundRemover:
    def remove(self, data):
        """
        The function remove the static background reflection from the measurements.
        Note that the all the values are absolute because the output format of the Walabot
        :param data:
        :return:
        """

        # Taking absolute value of the data before processing
        data = np.absolute(data)

        # After removing the background, still go head to take absolute value
        data = np.absolute(remove_background(data))
        return data

class NoiseAttenuator:
    def __init__(self):
        pass

    def _slice_data(self, data, fast_time, slow_time):
        """
        Slice data in order to the length of row and column are divisible by x and y
        :param data:
        :param fast_time: average every x elements across columns
        :param slow_time: average every y elements across rows
        :return: sliced data
        """
        x_curtailment = data.shape[1] % fast_time
        y_curtailment = data.shape[0] % slow_time
        data = data[0:data.shape[0] - y_curtailment, 0:data.shape[1] - x_curtailment]
        return data

    def attenuate(self, data, fast_time, slow_time):
        # Attenuate noises by average per n adjacent times scan
        def average_across_column(row, size):
            return np.mean(row.reshape(row.size // size, size), axis=1)

        data = self._slice_data(data, fast_time, slow_time)

        # average along x-axis of data
        averaged_diff = np.apply_along_axis(average_across_column, 1, data, fast_time)

        # average along y-axis of data
        averaged_diff = np.apply_along_axis(average_across_column, 0, averaged_diff, slow_time)

        return averaged_diff

class SignalSmoother:
    """
    This smoother smooth signals using savgol algorithm
    """

    def __init__(self, p):
        self.p = p

    def smooth(self, motion_path, static_indices_range):
        """
        Only smooth the dynamic section of a whole motion path
        :param motion_path: The coarse  motion path before smoothing
        :param static_indices_range: The array of tuples contains the motion ranges
        :return: Motion_path include the complete motion path. The smoothed path only return
        the section of path that is smoothed
        """
        start = 0
        end = 0

        head_tuple = static_indices_range[0]
        tail_tuple = static_indices_range[-1]

        if head_tuple[0] == 0 and tail_tuple[1] == motion_path.size - 1:
            start = static_indices_range[0][1] + 1
            end = static_indices_range[-1][0] + 1

        if head_tuple[0] == 0 and tail_tuple[1] != motion_path.size - 1:
            start = static_indices_range[0][1] + 1
            end = static_indices_range[-1][1] + 1

        if head_tuple[0] != 0 and tail_tuple[1] == motion_path.size - 1:
            start = 0
            end = tail_tuple[0] + 1

        if head_tuple[0] != 0 and tail_tuple[1] != motion_path.size - 1:
            start = 0
            end = tail_tuple[1]

        smooth_target = motion_path[start:end]

        smoothed_path = self._set_savgol(smooth_target, self.p)

        np.put(motion_path, np.arange(start, end), smoothed_path)

        return motion_path, smoothed_path

    def _set_savgol(self, data, p):
        if data.size % 2 == 0:
            smoothed = savgol_filter(data, data.size - 1, p)
        else:
            smoothed = savgol_filter(data, data.size, p)
        return smoothed

class MotionAnalyzer:
    def __init__(self, smoother, fast_time_threshold, motion_amplitude_threshold, only_return_motions=True):
        self.only_return_motions = only_return_motions
        self.motion_amplitude_threshold = motion_amplitude_threshold
        self.fast_time_threshold = fast_time_threshold
        self.smoother = smoother

    def extract(self, data):
        """"""
        '''
        Preliminarily discovering all possible motion index comparing each scan based
        on the possible range of indices because of one's volume
        '''
        possible_indices = taking_motion_index(self._take_index, data, threshold=self.fast_time_threshold)

        '''
        Finding the motion part of the time-series data.
        This steps return a list of amplitudes of the change betweentwo scans
        '''
        amplitude_range = self._compute_amplitude_difference_range(data)

        # Eliminate the indices that are thought as no motions
        motion_indices = self._extract_motion_indices(amplitude_range, self.motion_amplitude_threshold).tolist()

        # Set static value of static positions as zero
        motion_path = self._set_static_indices(possible_indices, motion_indices)

        # Interpolating static history
        motion_path, static_indices_range = self._interpolate_static_history(motion_path)

        # Smooth the curve
        motion_path, smoothed_path = self.smoother.smooth(motion_path, static_indices_range)

        if self.only_return_motions:
            return smoothed_path
        else:
            return motion_path

    def _interpolate_static_history(self, motion_indices):
        """
        This function interpolates the positions that are not shown due to static
        The length of the motion_indices shall be at least 3
        :param motion_indices:
        :return:
        """
        static_indices = discover_static_status(motion_indices)

        for start, end in static_indices:
            if start == 0 and (end + 1) < motion_indices.size:
                interpolated_position = motion_indices[end + 1]
                for i in np.arange(start, end + 1):
                    motion_indices[i] = interpolated_position

            if end == motion_indices.size - 1:
                interpolated_position = motion_indices[start - 1]
                for i in np.arange(start, end + 1):
                    motion_indices[i] = interpolated_position

            if start != 0 and end != motion_indices.size - 1:
                interpolated_position = (motion_indices[start - 1] + motion_indices[end + 1]) / 2
                for i in np.arange(start, end + 1):
                    motion_indices[i] = interpolated_position

        return motion_indices, static_indices

    def _extract_motion_indices(self, data, std_times):
        """
        This function return indices that meet
        the criterion that a index can be thought
        as a "motion"
        :param data:
        :param std_times:
        :return:
        """
        std_am = np.std(data)
        med_am = np.median(data)
        motion_am = np.where(
            (data > (med_am + std_times * std_am)))
        return motion_am[0]

    def _set_static_indices(self, possible_indices, motion_indices):
        for i in np.arange(0, possible_indices.size):
            if i not in motion_indices:
                possible_indices[i] = 0

        return possible_indices

    def _take_index(self, row, threshold):
        """
        Take indices from candidate indices array.
        the n represent the number of largest amplitudes that calculated
        by the threshold. Then taking the indices of the n-largest amplitudes.

        :param row:
        :param threshold:
        :return:
        """
        indices = np.argsort(row)
        n = int(row.size * (1 - threshold))
        return np.amin(indices[-n:])

    def _taking_motion_index(self, take_index, data, threshold):
        """
        The function takes indices of max amplitudes for each PRI.
        Note that, the each tuples contains of the data contain 8192 or 4096 samples

        :param take_index:
        :param data:
        :param threshold:
        :return: the return is a 1-d array that consists of the indices of max amplitudes in each tuple
        """

        return np.apply_along_axis(func1d=take_index,
                                   axis=1,
                                   arr=data,
                                   threshold=threshold
                                   )

    def _compute_amplitude_difference_range(self, data):
        """
        Return max amplitude of the current fast-time signals
        :param data:
        :return:
        """

        def subtract(row):
            return np.max(row)

        return np.apply_along_axis(func1d=subtract,
                                   axis=1,
                                   arr=data
                                   )

class DataProcessor:
    def __init__(self, background_remover, motion_analyzer, ):
        self.motion_analyzer = motion_analyzer
        self.background_remover = background_remover

    def process(self, data_set):
        """

        Current Hypotheses:
            1. The motion of the object is assumed as continuous without interrupting in the middle
            2. The motion signals take up small portion of the whole slow-time signals
        :param data_set:
        :return:
        """
        background_removed_data = self.background_remover.remove(data_set)
        motions = self.motion_analyzer.extract(background_removed_data)
        return motions


from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.forms.models import model_to_dict
from datetime import datetime
from .models import Student, SupportDocument
from .forms import StudentForm
from .decorators import can_edit_data
from school.models import Profile

@login_required
@can_edit_data
def student(request, serial):
    try:
        request.user.profile
    except Profile.DoesNotExist:
        return redirect("school:profile")

    student = Student.objects.filter(school=request.user, serial=serial)[0]
    blank_warning = []

    if not student.f_name or student.f_name == "":
        blank_warning.append("Father's Name is BLANK")

    if not student.m_name or student.m_name == "":
        blank_warning.append("Mother's Name is BLANK")

    if (student.f_name == "" or student.f_name is None) and (
        student.g_indicator == "" or student.g_indicator is None
    ):
        if (student.m_name == "" or not student.m_name) and (
            student.f_name == "" or not student.f_name
        ):
            if not student.g_name or student.g_name == "":
                blank_warning.append("Guardian's Name is BLANK")

    if not student.dob or student.dob == "":
        blank_warning.append("Date of Birth is BLANK")

    if student.name == student.f_name:
        blank_warning.append("Candidate Name and Father's Name are SAME")

    if student.name == student.m_name:
        blank_warning.append("Candidate Name and Mother's Name are SAME")

    if (student.m_name == student.f_name) and (student.m_name or student.f_name):
        blank_warning.append("Mother's Name and Father's Name are SAME")

    context = {"student": student, "blank_warning": blank_warning}
    return render(request, "student/student.html", context)

@login_required
@can_edit_data
def select_student(request, serial):
    try:
        request.user.profile
    except Profile.DoesNotExist:
        return redirect("school:profile")

    student = Student.objects.filter(school=request.user, serial=serial)[0]
    dob = student.dob

    extra_warning = ""

    if (not student.f_name and not student.m_name and student.g_name) or (
        student.f_name == "" and student.m_name == "" and student.g_name
    ):
        extra_warning = "Warning! Father's Name and Mother's Name are blank. "

    if (not student.f_name and not student.m_name and not student.g_name) or (
        student.f_name == "" and student.m_name == "" and student.g_name == ""
    ):
        messages.error(
            request,
            f"Student with \"Blank Father's Name, Mother's Name or Guardian's Name\",  {student.name} can not be selected.",
        )
        return redirect(student.get_absolute_url())

    elif not dob or dob == "":
        messages.error(
            request,
            f'Student with "Blank Date of Birth",  {student.name} can not be selected.',
        )
        return redirect(student.get_absolute_url())

    elif datetime.strptime(dob, "%d%m%y") and datetime.strptime(
        dob, "%d%m%y"
    ) > datetime.strptime("311009", "%d%m%y"):
        messages.error(
            request, f"Under-Age Student,  {student.name} can not be selected."
        )
        return redirect(student.get_absolute_url())

    student.status = "1"
    student.save()

    try:
        next_student = Student.objects.filter(
            school=request.user, serial__gt=serial
        ).first()
        messages.success(
            request,
            f"{extra_warning}Student {student.name} has been marked as Selected.",
        )
        return redirect(next_student.get_absolute_url())
    except Exception:
        return redirect("school:student_list")

@login_required
@can_edit_data
def not_select_student(request, serial):
    try:
        request.user.profile
    except Profile.DoesNotExist:
        return redirect("school:profile")

    student = Student.objects.filter(school=request.user, serial=serial)[0]
    extra_warning = ""

    if (not student.f_name and not student.m_name and student.g_name) or (
        student.f_name == "" and student.m_name == "" and student.g_name
    ):
        extra_warning = "Warning! Father's Name and Mother's Name are blank. "

    student.status = "2"
    student.save()

    try:
        next_student = Student.objects.filter(
            school=request.user, serial__gt=serial
        ).first()
        messages.warning(
            request,
            f"{extra_warning}Student {student.name} has been marked as NOT Selected",
        )
        return redirect(next_student.get_absolute_url())
    except Exception:
        return redirect("school:student_list")

@login_required
@can_edit_data
def edit_student(request, serial):
    try:
        request.user.profile
    except Profile.DoesNotExist:
        return redirect("school:profile")

    student = Student.objects.filter(school=request.user, serial=serial)[0]
    student_dict = model_to_dict(
        student, fields=[field.name for field in student._meta.fields]
    )
    student_dict["g_name"] = student.get_guardian_name()
    try:
        student_dict["dob"] = datetime.strptime(student_dict["dob"], "%d%m%y")
    except (ValueError, KeyError, TypeError):
        student_dict["dob"] = ""
    try:
        document = SupportDocument.objects.get(student=student).document
    except SupportDocument.DoesNotExist:
        document = None

    student_dict["document"] = document

    form = StudentForm(initial=student_dict)

    if request.method == "POST":
        form = StudentForm(request.POST, request.FILES, instance=student)
        if form.is_valid():
            support_document = form.cleaned_data.get("document")
            edited = form.cleaned_data.get("edited")
            form.cleaned_data.pop("edited")

            s = form.save(commit=False)
            original_profile_picture = Student.objects.get(
                school=request.user, serial=serial
            ).profile_picture
            if original_profile_picture != s.profile_picture:
                if not original_profile_picture:
                    s.profile_pic_ind = "n"
                else:
                    s.profile_pic_ind = "d"

            try:
                dob = form.cleaned_data.get("dob").strftime("%d%m%y")
            except AttributeError:
                dob = None
            s.dob = dob
            if edited == "1":
                s.edited = True

                s_document, s_document_created = SupportDocument.objects.get_or_create(
                    student=student
                )
                s_document.document = support_document
                s_document.save()
            s.save()
            messages.success(
                request,
                f"Information for student {student.name} has been updated. Please SELECT / NOT SELECT the student.",
            )
            return redirect(student.get_absolute_url())

    context = {"form": form, "student": student}
    return render(request, "student/form.html", context)


"""This module, bookmarks, serves as the core of the Bookmarks application, defining key attributes, classes,
and methods that shape the app's functionality and aesthetics. This module also houses the application's configurable
properties and default settings.

Initialization methods for the application can be found in :mod:`~bookmarks.common.setup`. Hard-coded default
properties are contained within :mod:`~bookmarks.common.core`. Configurable properties, including color schemes and
size settings, are loaded from ./rsc/conf.json during runtime.

This module allows for direct submodule access. For example:

.. code-block:: python
    :linenos:

    # bookmarks.common.setup.initialize(common.EmbeddedMode) can be imported as
    from bookmarks import common
    common.initialize(common.EmbeddedMode)

The Bookmarks application operates in two modes: standalone and embedded in a PySide2 environment. The app's base layers
are initialized using:

.. code-block:: python
    :linenos:

    from bookmarks import common
    common.initialize(common.EmbeddedMode) # or common.StandaloneMode

To start Bookmarks in :attr:`~bookmarks.common.core.StandaloneMode`, use :func:`bookmarks.exec_()`. The
:attr:`~bookmarks.common.core.EmbeddedMode` is designed for running the application within a host DCC, a feature
currently utilized only by the Maya plugin. Refer to :mod:bookmarks.maya and :mod:`bookmarks.common` for related
methods.

This module also houses widget instance bindings for various components of the application, such as the main widget,
tray widget, and several editor widgets. The initial values of module-level variables are stored in the
`__initial_values__` dictionary for potential later use.

This top module additionally makes various submodules available, including those related to core functionalities,
data handling, environment settings, font settings, UI elements, and more.

"""
debug_on = False
typecheck_on = False
init_mode = None
active_mode = None
signals = None
settings = None

ui_scale_factor = 1.0  # Global ui scaling factor
dpi = 72.0

stylesheet = None
cursor = None
font_db = None

servers = {}
default_bookmarks = {}
bookmarks = {}
favourites = {}
hashes = {}
timers = {}
font_cache = {}
db_connections = {}

active_paths = None

item_data = {}
watchers = {}

delegate_paths = {}
delegate_rectangles = {}
delegate_text_segments = {}
delegate_subdir_rectangles = {}
delegate_bg_subdir_rectangles = {}
delegate_bg_brushes = {}
delegate_clickable_rectangles = {}
delegate_description_rectangles = {}

color_cache = {}
color_cache_str = {}

elided_text = {}

viewer_widgets = {}

pixel_ratio = None
oiio_cache = None

image_resource_list = {}
image_resource_data = {}
image_cache = {}

token_configs = {}

# Widget instance bindings
main_widget = None
tray_widget = None
maya_widget = None
maya_button_widget = None
gallery_widget = None
launcher_widget = None
message_widget = None
preference_editor_widget = None
job_editor = None
bookmark_property_editor = None
asset_property_editor = None
clipboard_editor = None
file_saver_widget = None
publish_widget = None
maya_export_widget = None
ffmpeg_export_widget = None
akaconvert_widget = None
screen_capture_widget = None
pick_thumbnail_widget = None
notes_widget = None

# Save the initial module values for later use
__initial_values__ = {
    k: (v.copy() if isinstance(v, dict) else v) for (k, v) in
    locals().copy().items() if not k.startswith('__')
}

# Make submodules available from this top module
from .core import *
from .data import *
from .env import *
from .font import *
from .monitor import *
from .sequence import *
from .active_mode import *
from .clipboard import *
from .settings import *
from .setup import *
from .signals import *
from .ui import *


import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit

def linear(x, a,b):
    return a*x+b

def lei_de_potencia(x,a,b):

	return a*x**b

def diretorio(caso, nome):
	matriz = '/home/eude/Desktop/IC/caos/distri_grau'
	casos = ['/LM_p1','/LM_int','/LM_fbp','/LM_c1','/LM_c2','/LM_fc']
	barra = '/'
	tipo = '.txt'

	nome = str(nome)
	caso = float(caso)

	string=''

	if (caso == 3.5):
		string = str(matriz+casos[0]+barra+nome+tipo)
	elif ((caso - 3.56995)<0.000001):
		string = str(matriz+casos[1]+barra+nome+tipo)
	elif ((caso - 3.857)<0.0001):
		string = str(matriz+casos[2]+barra+nome+tipo)
	elif ((caso - 3.87)<0.001):
		string = str(matriz+casos[3]+barra+nome+tipo)
	elif ((caso - 3.89)<0.001):
		string = str(matriz+casos[4]+barra+nome+tipo)
	elif (caso == 4):
		string = str(matriz+casos[5]+barra+nome+tipo)
	else:
		print("Caso invalido")

	return string

u = float(input('Digite um dos casos abaixo:\n 3.5 \n 3.56995 \n 3.857 \n 3.87 \n 3.89 \n 4.00 \n '))
v = int(input('Digite o tamanho do arquivo txt: '))

pasta = diretorio(u,v)

arq = open(pasta, 'r')

vec = arq.readlines() # Transformando cada linha em entradas da lista
for i in range(len(vec)):
	vec[i] = vec[i].split(",") # Quebrando cada todas as linhas até onde tem vírgula
arq.seek(0)
for i in range(len(vec)):
	for j in range(2):
		vec[i][j] = float(vec[i][j]) # Convertendo os valores em float e adicionando ao array vec

arq.seek(0)

k = []
p = []
#p_= []
print(p)
for i in range(len(vec)):
	for j in range(2):
		if j == 0:
			k.append(vec[i][j])
		if j == 1:
			p.append((vec[i][j]))
#			p_.append(vec[i][j])

x = np.log(np.array(k))
y = np.log(np.array(p))
#y_ = np.array(p_)

#popt, pcov = curve_fit(linear, x, y)

popt, pcov = curve_fit(linear, x, y)

fig, ax = plt.subplots()

x_plot = np.linspace(x.min(), x.max(), 2000)
y_plot = linear(x_plot, *popt)

plt.xlabel(r"$ln k$")
plt.ylabel(r"$ln p(k)$")
ax.plot(x, y, 'ro')
ax.plot(x_plot, y_plot, label=r'$\alpha$ = -1.41')

print(popt)

plt.legend()
plt.show()

arq.close()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#Outioua Mohand -- Jonathan Soleillet
#24 novembre 2015 --TP5 : Compression - Partie 3 et 4 : Huffman

'''
Implantation de l'algorithme de Huffman

@author FIL - IEEA - Univ. Lille (août 2015)
'''

import doctest
import operator
from huffman_tree import HuffmanTree
import coding
import struct
from coding_decoding_words import *

def symbol_occurrences(stream):
    '''
    Read the stream and count the occurrences of each symbol in the stream

    :param stream: a stream opened (in read mode and in binary mode)
    :return: A dictionary whose keys are symbols and the associated values are\
    the corresponding number of occurrences
    :rtype: dict
    :Examples:

    >>> from io import StringIO # StringIO is used to have examples based on strings.
    >>> symbol_occurrences(StringIO("ababcaba")) == {'c': 1, 'b': 3, 'a': 4}
    True
    >>> symbol_occurrences(StringIO('aaaa')) == {'a': 4}
    True
    >>> symbol_occurrences(StringIO(''))
    {}
    >>> symbol_occurrences(StringIO('abcd')) == {'a': 1, 'b': 1, 'c': 1, 'd': 1}
    True
    '''
    counters = dict()
    byte = stream.read(1)
    while len(byte) > 0 :
        if byte in counters:
            counters[byte] = counters[byte] + 1
        else:
            counters[byte] = 1
        byte = stream.read(1)
    return counters

#9

#La 1er liste sont les items du dictionnaire triée par leur nombre d'occurence
#La second permet de crée l'arbre de huffman par rapport à la liste triée
#On utilise deux liste pour ne pas faire le trie en même temps que la création que l'arbre de huffman sinon on doit parcourrir la liste à chaque fois pour pouvoir faire l'arbre.
#Donc on diminue le coût de l'algorithme
def create_forest(occurrences):
    '''
    Create the initial list of Huffman trees based on the dictionary of
    symbols given in parameter.

    :param occurrences: Number of occurrences of each symbol.
    :type occurrences: dict
    :return: A list sorted in ascending order on the number of occurrences\
    and on the symbols of Huffman trees of all symbols provided in\
    `occurrences`.
    :Examples:

    >>> create_forest({'a': 4, 'c': 2, 'b': 1})
    [|b:1|, |c:2|, |a:4|]
    >>> create_forest({'e': 1, 'f': 1, 'g': 1, 'h': 1, 'a':2})
    [|e:1|, |f:1|, |g:1|, |h:1|, |a:2|]
    '''
    #key=lambda item: (item[1], item[0]) permet de trier par rapport à l'items 1 du dictionnaire
    #sinon le trie va se faire par ordre lexicographique (a,b,c,...,z)
    sorted_occs = sorted(occurrences.items(), key=lambda item: (item[1], item[0]))
    forest = [HuffmanTree(leaf[0], leaf[1]) for leaf in sorted_occs]
    return forest

def pop_least_element(list1, list2):
    '''
    Get and remove the lowest element from two lists sorted in ascending order.

    :param list1: First list sorted in ascending order
    :type list1: list
    :param list2: Second list sorted in ascending order
    :type list2: list
    :return: The lowest element among the two lists
    :UC: The two lists are sorted in ascending order and there is at least\
    one element among the two lists.
    :Examples:

    >>> pop_least_element([1], [2])
    1
    >>> pop_least_element([2], [1])
    1
    >>> pop_least_element([], [1])
    1
    >>> pop_least_element( [1], [])
    1
    '''
    assert(len(list1) + len(list2) >= 1)
    if len(list1) == 0:
        return list2.pop(0)
    if len(list2) == 0:
        return list1.pop(0)
    if list2[0] < list1[0]:
        return list2.pop(0)
    return list1.pop(0)

def create_huffman_tree(occurrences):
    '''
    Return a Huffman tree of the symbols given in `occurrences`.

    :param occurrences: Number of occurrences of each symbol.
    :type occurrences: dict
    :return: Return a single Huffman tree (obtained with Huffman algorithm)\
    of the symbols in `occurrences`.
    :rtype: huffman_tree.HuffmanTre
    :Examples:

    >>> create_huffman_tree({'a': 4, 'b': 1, 'c': 2})
    |bca:7|_<|bc:3|_<|b:1|, |c:2|>, |a:4|>
    >>> create_huffman_tree({'a': 1, 'b': 1, 'c': 2})
    |cab:4|_<|c:2|, |ab:2|_<|a:1|, |b:1|>>
    '''
    symbol_list = create_forest(occurrences)
    tree_list = []

    while len(tree_list) + len(symbol_list) != 1:
        (elem1, elem2) = (pop_least_element(symbol_list, tree_list),\
                          pop_least_element(symbol_list, tree_list))
        new_tree = HuffmanTree(left = elem1, right=elem2)
        tree_list.append(new_tree)

    if len(tree_list) == 1:
        return tree_list[0]
    return symbol_list[0]

def get_coding_from_tree(tree, code=''):
    '''
    Get the codes associated to the symbols.

    :param tree: A HuffmanTree
    :type tree: huffman_tree.HuffmanTree
    :param code: (optional parameter) the path that was followed to access the\
    current root of the tree
    :return: a list of tuples. Each tuple is made of a symbol and a code.\
    The order of the tuples in the list does not matter
    :rtype: list
    :Examples:

    >>> c=get_coding_from_tree(create_huffman_tree({'a': 4, 'b': 1, 'c': 2}))
    >>> len(c)
    3
    >>> c.count(('a', '1')) == 1
    True
    >>> c.count(('b', '00')) == 1
    True
    >>> c.count(('c', '01')) == 1
    True
    '''
    if tree.isLeaf():
        return [(tree.symbol, code)]
    return get_coding_from_tree(tree.left, code + '0') \
        + get_coding_from_tree(tree.right, code + '1')

def huffman_coding(tree):
    '''
    Creates a Huffman coding from a Huffman tree.

    :param tree: A Huffman tree
    :type tree: huffman_tree.HuffmanTree
    :return: A Huffman coding based on the Huffman tree given in parameter
    :rtype: coding.Coding
    :Examples:

    >>> c = huffman_coding(create_huffman_tree({'a': 4, 'b': 1, 'c': 2}))
    >>> c.code('a') + ' ' + c.code('b') + ' ' + c.code('c')
    '1 00 01'
    >>> c = huffman_coding(create_huffman_tree({'a': 1, 'b': 2, 'c': 3, 'd': 5}))
    >>> c.code('a') + ' ' + c.code('b') + ' ' + c.code('c') + ' '\
    + c.code('d')
    '110 111 10 0'
    '''
    result = get_coding_from_tree(tree, '')
    alphabet = list(map(lambda i: i[0], result))
    codes = list(map(lambda i: i[1], result))
    return coding.create(alphabet, codes)

def write_occurrences(occurrences, filename):
    '''
    Write the symbol occurrences in the given file

    :param occurrences: The dictionary of symbol occurrences
    :type occurrences: dict
    :param filename: The filename where the occurrences must be written.
    :type filename: str
    '''

    stream = open(filename, 'wb')
    for c in occurrences:
        stream.write(bytes(c))
        stream.write(bytes(struct.pack('i',occurrences[c])))
    stream.close()
def read_occurrences(filename):
    '''
    Read the symbol occurrences from the given file.

    :param filename: The filename where the occurrences must be read.
    :type filename: str
    :return: A dictionary of the symbol occurrences
    :rtype: dict
    :Examples:

    >>> import tempfile; temp = tempfile.NamedTemporaryFile()
    >>> d = {b'c': 1, b'b': 3, b'a': 4}
    >>> write_occurrences(d, temp.name)
    >>> read_occurrences(temp.name) == d
    True
    >>> d = {b'e': 1, b'f': 1, b'g': 1, b'h': 1, b'a':2}
    >>> write_occurrences(d, temp.name)
    >>> read_occurrences(temp.name) == d
    True
    '''
    stream = open(filename,'rb')
    byte = stream.read(1)
    occurence = dict()
    while byte != b'':
        key = byte
        byte = stream.read(struct.calcsize('i'))
        value = struct.unpack('i',byte)
        occurence[key] = value[0]
        byte = stream.read(1)
    stream.close()
    return occurence

def huffman_encode(filename, out_filename):
    '''
    Encode a file using Huffman algorithm and writes the result to
    an other file.

    Two files will be created. One called `out_filename` containing
    a Huffman encoding of the input file. Another one called
    `out_filename`+".code" which will contain the occurrences of each
    symbol.

    :param filename: The filename of the file to be encoded.
    :type filename: str
    :param out_filename: The filename of the file where the resulting\
    encoding will be stored.
    :type out_filename: str
    '''
    occurence = dict()
    stream = open(filename, 'rb')
    # Calcul du nombre d'occurrences
    occurence =symbol_occurrences(stream)
    # Création du codage de Huffman
    codage = huffman_coding(create_huffman_tree(occurence))
    # Ecriture du fichier stockant le dictionnaire d'occurrences
    write_occurrences(occurence,out_filename.replace(".encode","")+'.code')
    # Mise de la tête de lecture au début du fichier pour le reparcourir
    stream.seek(0)
    # Parcours du fichier et encodage des symboles lus
    byte = stream.read(1)
    s = ''
    while byte != b'':
        s = s + codage.code(byte)
        byte = stream.read(1)
    write_binary_string_in_file(s,out_filename)

def prefix_tree_decoding(bits, tree):
    '''
    Return the decoding of the binary string given in parameter
    using the Huffman tree `tree`.

    :param bits: a binary string (only made of 0s and 1s)
    :type bits: str
    :param tree: a Huffman tree
    :type tree: huffman_tree.HuffmanTree
    :return: Return the concatenation of symbols represented by the binary string.\
    The binary string is decoded using the Huffman tree.
    :rtype: bytes
    :UC: The binary string must end in a leaf.
    :Examples:

    >>> tree = create_huffman_tree({b'a': 1, b'b': 2, b'c': 3, b'd': 5})
    >>> prefix_tree_decoding('111110100111111110', tree)
    b'bacdbba'
    '''
    noeud = tree
    sortie = b''
    for bit in bits:
        if noeud.isLeaf():
            sortie += noeud.symbol
            noeud = tree
        if bit == '0':
            noeud = noeud.left
        else:
            noeud = noeud.right
    assert(noeud.isLeaf()), "La chaine devrait se terminer sur une feuille"
    sortie += noeud.symbol
    return sortie

def huffman_decode(filename, out_filename):
    '''
    Decode a file encoded with a Huffman encoding.

    :param filename: the file name of the Huffman encoded file
    :type filename: str
    :param out_filename: the file name where the decoding will be stored
    :type out_filename: str
    '''
    temp = filename
    temp = temp.replace(".encode","")
    occurence = read_occurrences(temp+'.code')
    tree = create_huffman_tree(occurence)

    out_file = open(out_filename,'wb')
    s = read_file(filename)
    byte = prefix_tree_decoding(s,tree)
    print(byte)
    out_file.write(byte)
    out_file.close()

#huffman_encode("huffman_skeleton.py","huffman_skeleton.encode")

#13

#1
#huffman_encode("huffman_skeleton.py","huffman_skeleton.encode")
#huffman_decode("huffman_skeleton.encode","huffman_skeleton.decode")

#la taille du fichier compressé est de 5200 octets

#2
#Pour en déduire la longueur moyenne :

#la taille du fichier non compréssé est de 8800 octets, sa longueur moyenne est de 8
# la taille du fichier compréssé est de 5200 octets, sa longueur moyenne est de x

#Grâce au produit en croix :: x = 5200 * 8 / 8800  | x = 4.7
# la longueur du fichier non compressé est de 4.7

#3
#l'entropie du fichier original est de 4.69, sa taille en octet est 8880
#l'entropie du fichier compressé est de 7.76, sa taille en octet est de 5200

#produit en croix :
#8800 8
#x   4,69
#8800 * 4,69/8 = x
# x = 5159 ocets
#la taille du fichier compressé s'il était compressé avec un codage de longueur moyenne
#vallent l'entropie serait de 5159

#4

# on prends la valeur supérieur de l'entropie du fichier compressé pour avoir la longueur fixe minimale donc 5 bits
#8800*5/8 = 5500

#la taille du fichier compressé si il était un codage de longueur fixe serait de 5500 octets

#14

#En fesant diff les deux fichiers sont bien identiques

#15

#huffman_encode("cigale.txt","cigale.encode")
#huffman_encode("sonnet18.txt","cigale.encode")
#huffman_encode("morse.mp3","morse_mp3.encode")
#huffman_encode("morse.wav","morse_wav.encode")
#huffman_encode("entropy.py","entropy.encode")
#huffman_encode("entropy.zip","entropy_zip.encode")
#huffman_encode("codage.bmp","codage_bmp.encode")
#huffman_encode("codage.png","codage_png.encode")

#morse.wav,codage.png et morse.mp3 ne peuvent plus  être optimisé ( proche de 0% )
#le fichier zip n'a été optimisé car la valeur théorique était de 1.9% elle passe à 1.3%
#cigale.txt et sonnet18.txt ont été optimisé d'environ 34% car les valeurs théoriques étaient de 43.65% et 45.03% et elles passent d'environ 9%
#codage.bmp a été optimisé de 37% car la valeur était de 44% et on passe à 7%
#entropy.py a été optimisé de 38% car la valeur théoriques était de 41%


import argparse
import os
import time
import numpy as np
from keras.layers import Conv2D, Input, BatchNormalization, LeakyReLU, ZeroPadding2D, UpSampling2D
from keras.layers.merge import add, concatenate
from keras.models import Model, load_model
import struct
import cv2
import sys
import scipy.io as sio
import gc
import tensorflow as tf
import pickle
from keras.backend.tensorflow_backend import set_session
np.set_printoptions(threshold=sys.maxsize)
#os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID"
#os.environ["CUDA_VISIBLE_DEVICES"]="0"
config = tf.ConfigProto()
config.log_device_placement = False
config.gpu_options.allow_growth = True
sess = tf.Session(config=config)
set_session(sess)  # set this TensorFlow session as the default session for Keras

argparser = argparse.ArgumentParser(
    description='Use yolov3 network to crop the image')

argparser.add_argument(
    '-i',
    '--image',
    help='path to image file')

argparser.add_argument(
    '-o',
    '--output',
    help='path to output file')

def preprocess_input(image, net_h, net_w):
    new_h, new_w, _ = image.shape

    # determine the new size of the image
    if (float(net_w)/new_w) < (float(net_h)/new_h):
        new_h = (new_h * net_w)/new_w
        new_w = net_w
    else:
        new_w = (new_w * net_h)/new_h
        new_h = net_h

    # resize the image to the new size
    resized = cv2.resize(image[:,:,::-1]/255., (int(new_w), int(new_h)))

    # embed the image into the standard letter box
    new_image = np.ones((net_h, net_w, 3)) * 0.5
    new_image[int((net_h-new_h)//2):int((net_h+new_h)//2), int((net_w-new_w)//2):int((net_w+new_w)//2), :] = resized
    new_image = np.expand_dims(new_image, 0)

    return new_image

class BoundBox:
    def __init__(self, xmin, ymin, xmax, ymax, objness = None, classes = None):
        self.xmin = xmin
        self.ymin = ymin
        self.xmax = xmax
        self.ymax = ymax

        self.objness = objness
        self.classes = classes

        self.label = -1
        self.score = -1

    def get_label(self):
        if self.label == -1:
            self.label = np.argmax(self.classes)

        return self.label

    def get_score(self):
        if self.score == -1:
            self.score = self.classes[self.get_label()]

        return self.score

def _interval_overlap(interval_a, interval_b):
    x1, x2 = interval_a
    x3, x4 = interval_b

    if x3 < x1:
        if x4 < x1:
            return 0
        else:
            return min(x2,x4) - x1
    else:
        if x2 < x3:
             return 0
        else:
            return min(x2,x4) - x3

def _sigmoid(x):
    return 1. / (1. + np.exp(-x))

def bbox_iou(box1, box2):
    intersect_w = _interval_overlap([box1.xmin, box1.xmax], [box2.xmin, box2.xmax])
    intersect_h = _interval_overlap([box1.ymin, box1.ymax], [box2.ymin, box2.ymax])

    intersect = intersect_w * intersect_h

    w1, h1 = box1.xmax-box1.xmin, box1.ymax-box1.ymin
    w2, h2 = box2.xmax-box2.xmin, box2.ymax-box2.ymin

    union = w1*h1 + w2*h2 - intersect

    return float(intersect) / union

def decode_netout(netout, anchors, obj_thresh, nms_thresh, net_h, net_w):
    grid_h, grid_w = netout.shape[:2]
    nb_box = 3
    netout = netout.reshape((grid_h, grid_w, nb_box, -1))
    nb_class = netout.shape[-1] - 5

    boxes = []

    netout[..., :2]  = _sigmoid(netout[..., :2])
    netout[..., 4:]  = _sigmoid(netout[..., 4:])
    netout[..., 5:]  = netout[..., 4][..., np.newaxis] * netout[..., 5:]
    netout[..., 5:] *= netout[..., 5:] > obj_thresh

    for i in range(grid_h*grid_w):
        row = i / grid_w
        col = i % grid_w

        for b in range(nb_box):
            # 4th element is objectness score
            objectness = netout[int(row)][int(col)][b][4]
            #objectness = netout[..., :4]

            if(objectness.all() <= obj_thresh): continue

            # first 4 elements are x, y, w, and h
            x, y, w, h = netout[int(row)][int(col)][b][:4]

            x = (col + x) / grid_w # center position, unit: image width
            y = (row + y) / grid_h # center position, unit: image height
            w = anchors[2 * b + 0] * np.exp(w) / net_w # unit: image width
            h = anchors[2 * b + 1] * np.exp(h) / net_h # unit: image height

            # last elements are class probabilities
            classes = netout[int(row)][col][b][5:]

            box = BoundBox(x-w/2, y-h/2, x+w/2, y+h/2, objectness, classes)
            #box = BoundBox(x-w/2, y-h/2, x+w/2, y+h/2, None, classes)

            boxes.append(box)

    return boxes

def correct_yolo_boxes(boxes, image_h, image_w, net_h, net_w):
    if (float(net_w)/image_w) < (float(net_h)/image_h):
        new_w = net_w
        new_h = (image_h*net_w)/image_w
    else:
        new_h = net_w
        new_w = (image_w*net_h)/image_h

    for i in range(len(boxes)):
        x_offset, x_scale = (net_w - new_w)/2./net_w, float(new_w)/net_w
        y_offset, y_scale = (net_h - new_h)/2./net_h, float(new_h)/net_h

        boxes[i].xmin = int((boxes[i].xmin - x_offset) / x_scale * image_w)
        boxes[i].xmax = int((boxes[i].xmax - x_offset) / x_scale * image_w)
        boxes[i].ymin = int((boxes[i].ymin - y_offset) / y_scale * image_h)
        boxes[i].ymax = int((boxes[i].ymax - y_offset) / y_scale * image_h)

def do_nms(boxes, nms_thresh):
    if len(boxes) > 0:
        nb_class = len(boxes[0].classes)
    else:
        return

    for c in range(nb_class):
        sorted_indices = np.argsort([-box.classes[c] for box in boxes])

        for i in range(len(sorted_indices)):
            index_i = sorted_indices[i]

            if boxes[index_i].classes[c] == 0: continue

            for j in range(i+1, len(sorted_indices)):
                index_j = sorted_indices[j]

                if bbox_iou(boxes[index_i], boxes[index_j]) >= nms_thresh:
                    boxes[index_j].classes[c] = 0

def draw_boxes(image, boxes, labels, obj_thresh):
    for box in boxes:
        label_str = ''
        label = -1

        for i in range(len(labels)):
            if box.classes[i] > obj_thresh:
                label_str += labels[i]
                label = i
                print(labels[i] + ': ' + str(box.classes[i]*100) + '%')

        if label >= 0:
            cv2.rectangle(image, (box.xmin,box.ymin), (box.xmax,box.ymax), (0,255,0), 3)
            cv2.putText(image,
                        label_str + ' ' + str(box.get_score()),
                        (box.xmin, box.ymin - 13),
                        cv2.FONT_HERSHEY_SIMPLEX,
                        1e-3 * image.shape[0],
                        (0,255,0), 2)

    return image

def crop_image_based_on_boxes(image, output_path, fileCounter, boxes, labels, obj_thresh):
    count = 1
    h, w, _ = image.shape
    for box in boxes:
        label_str = ''
        label = -1
        maxval = obj_thresh
        for i in range(len(labels)):
            if box.classes[i] > maxval:
                label_str = labels[i]
                label = i
                maxval = box.classes[i]

        if label >= 0 and box.ymin < box.ymax and box.xmin < box.xmax:
            xmin = max(0, box.xmin)
            ymin = max(0, box.ymin)
            xmax = min(w, box.xmax)
            ymax = min(h, box.ymax)
            crop_image = image[ymin:ymax, xmin:xmax]
            if not os.path.exists(os.path.join(output_path, label_str + '/')):
                os.mkdir(os.path.join(output_path, label_str + '/'))
            output_filename = os.path.join(output_path, label_str + '/' + str(fileCounter) + '-' + str(count) + '.jpg')
            cv2.imwrite(output_filename, (crop_image).astype('uint8'))

        count = count + 1

def _main_(args):
    image_root_dir  = args.image
    output_root_dir = args.output

    # set some parameters
    net_h, net_w = 416, 416
    obj_thresh, nms_thresh = 0.5, 0.45
    anchors = [[116,90,  156,198,  373,326],  [30,61, 62,45,  59,119], [10,13,  16,30,  33,23]]
    labels = ["person", "bicycle", "car", "motorbike", "aeroplane", "bus", "train", "truck", \
              "boat", "traffic light", "fire hydrant", "stop sign", "parking meter", "bench", \
              "bird", "cat", "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", \
              "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", \
              "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", \
              "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", \
              "apple", "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", \
              "chair", "sofa", "pottedplant", "bed", "diningtable", "toilet", "tvmonitor", "laptop", "mouse", \
              "remote", "keyboard", "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", \
              "book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush"]

    # make the yolov3 model to predict 80 classes on COCO
    yolov3 = load_model('models/yolov3.h5');

    for x in os.listdir(image_root_dir):
        print(x)
        image_path_dir = os.path.join(image_root_dir, x)
        total_number_of_files = len([name for name in os.listdir(image_path_dir)])
        print(total_number_of_files)
        if not os.path.isdir(image_path_dir):
            continue
        print(image_path_dir)
        output_path_dir = os.path.join(output_root_dir, x + '/')
        if not os.path.exists(output_path_dir):
            os.mkdir(output_path_dir)
        print(output_path_dir)
        # read img from image path directory
        for fileCounter in range(1, total_number_of_files, 15):
            image_path = os.path.join(image_path_dir, 'image' + str(fileCounter) + '.jpg');
            print(image_path);
            # preprocess the image
            image = cv2.imread(image_path)
            image_h, image_w, _ = image.shape
            new_image = preprocess_input(image, net_h, net_w)

            # run the prediction
            yolos = yolov3.predict(new_image)
            boxes = []

            for i in range(len(yolos)):
                # decode the output of the network
                boxes += decode_netout(yolos[i][0], anchors[i], obj_thresh, nms_thresh, net_h, net_w)

            # correct the sizes of the bounding boxes
            correct_yolo_boxes(boxes, image_h, image_w, net_h, net_w)

            # suppress non-maximal boxes
            do_nms(boxes, nms_thresh)
            res_labels = [];
            for box in boxes:
                for i in range(len(labels)):
                    if box.classes[i] > obj_thresh:
                        res_labels.append(i);
            crop_image_based_on_boxes(image, output_path_dir, fileCounter, boxes, labels, obj_thresh)

if __name__ == '__main__':
    args = argparser.parse_args()
    _main_(args)


import os
from mollie.api.client import Client
from dotenv import load_dotenv

load_dotenv()
access_token = os.getenv("MOLLIE_ACCESS_TOKEN")

mollie_client = Client()
mollie_client.set_access_token(access_token)

balance_response = mollie_client.organizations.get('me')
balance = balance_response['balance']

print(f"Current balance: {balance}")


#!/usr/bin/python

# get the ECFP4 bits set for each molecule in a file; using rdkit's
# python bindings

from __future__ import print_function

import sys

from rdkit import Chem
from rdkit.Chem import AllChem

# ECFP4 is used in ZINC15
# In ECFP4, 4 stands for the diameter of the atom environment
fp_diameter = 4
# but rdkit wants a radius
fp_radius = fp_diameter / 2

def RobustSmilesMolSupplier(filename):
    with open(filename) as f:
        for line in f:
            split = line.split()
            smile = split[0]
            mol_name = split[1]
            mol = Chem.MolFromSmiles(smile)
            yield mol, mol_name

def get_mol_reader(filename):
    if filename.endswith(".smi"):
        return RobustSmilesMolSupplier(filename)
    else:
        print("get_mol_reader: fatal: unsupported file format: %s" % filename,
              file=sys.stderr)
        exit(1)

def get_name(mol):
    return mol.GetProp('_Name')

argc = len(sys.argv)
if argc != 2:
    #                           0          1
    print("ecfp6: fatal: usage: ./ecfp6.py filename.{smi|sdf}",
          file=sys.stderr)
    exit(1)

mol_reader = get_mol_reader(sys.argv[1])
i = 0
print("#mol_name,IC50 in mol/L (0.0 means unknown),ECFP4 set bits indexes");
for mol, mol_name in mol_reader:
    try:
        fp = AllChem.GetMorganFingerprint(mol, fp_radius)
        set_bits = fp.GetNonzeroElements()
        # set_bits: a dictionary; values are all ones
        # keys are the bit index in the fp
        print("%s,0.0,[" % mol_name, end='')
        first_time = True
        for key in set_bits:
            if first_time:
                print("%d" % key, end='')
                first_time = False
            else:
                print(";%d" % key, end='')
        print("]\n", end='')
    except:
        print("ecfp6: error: molecule at index %d" % i,
              file=sys.stderr)
    i = i + 1