import collections

class SymbolicStructureBase(object):
    FieldDetails = collections.namedtuple('FieldDetails', ('name', 'size', 'offset', 'ctype'))

    def __init__(self, state, address):
        self.state = state
        self.address = address
        self.fields = collections.OrderedDict()
        for spec in self._fields_:
            spec = self.FieldDetails(*spec)
            symbol = state.solver.BVS(spec.name, spec.size * 8)
            # setattr(self, name, symbol)
            type_ = "uint{0}_t".format(spec.size * 8)
            setattr(state.mem[address + spec.offset], type_, symbol)
            self.fields[spec.name] = symbol

    def get_name_from_addr(self, addr):
        ret = ""
        for spec in self._fields_:
            spec = self.FieldDetails(*spec)
            if addr == ( self.address + spec.offset ):
                ret = spec.name
                break

        return ret

                #major_list.append(spec.name)

    def get_MajorFunction(self):
        major_list = []
        for spec in self._fields_:
            spec = self.FieldDetails(*spec)
            if "IRP_MJ" in spec.name:
                major_list.append(spec.name)

        return major_list

    def get_offset(self, field_name):
        for spec in self._fields_:
            spec = self.FieldDetails(*spec)
            if spec.name == field_name:
                return spec.offset

    def eval_field(self, field_name, state=None):
        state = state or self.state
        symbol = self.fields[field_name]
        return state.solver.eval(symbol)

    def get_field_details(self, field_name):
        for spec in self._fields_:
            spec = self.FieldDetails(*spec)
            if spec.name == field_name:
                return spec
        raise RuntimeError('invalid field: ' + field_name)

    def read_field(self, field_name, state=None):
        state = state or self.state
        spec = self.get_field_details(field_name)
        return getattr(state.mem[self.address + spec.offset], "uint{0}_t".format(spec.size * 8))

    def read_field_single_valued(self, field_name, state=None):
        state = state or self.state
        field = self.read_field(field_name, state=state)
        if not state.solver.single_valued(field.resolved):
            return None
        return field.concrete

    def pp(self, state=None):
        state = state or self.state
        print("0x{0:08x} {1}".format(self.address, self.__class__.__name__))
        for spec in self._fields_:
            spec = self.FieldDetails(*spec)
            symbol = self.fields[spec.name]
            if state.solver.unique(symbol):
                value = "0x{0:x}".format(state.solver.eval(symbol))
            else:
                value = '???'
            print("0x{0:08x}     {1: <20} {2}".format(self.address + spec.offset, spec.name, value))

    def to_dict(self, state=None):
        state = state or self.state
        fields = []
        for spec in self._fields_:
            spec = self.FieldDetails(*spec)
            field = self.read_field(spec.name, state=state)
            fields.append({
                'name': spec.name,
                'type': spec.ctype,
                'value': None if field.resolved.symbolic else field.concrete
            })
        return {'name': self.__class__.__name__, 'fields': fields}

class DRIVER_OBJECT(SymbolicStructureBase):
# https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_driver_object
    _fields_ = (
        ('Type',                     2, 0x00, 'uint16_t Type'),
        ('Size',                     2, 0x02, 'uint16_t Size'),
        ('DeviceObject',             8, 0x08, 'void* DeviceObject'),
        ('Flags',                    8, 0x10, 'uint64_t Flags'),
        ('DriverStart',              8, 0x18, 'void* DriverStart'),
        ('DriverSize',               8, 0x20, 'uint64_t DriverSize'),
        ('DriverSection',            8, 0x28, 'void* DriverSection'),
        ('DriverExtension',          8, 0x30, 'void* DriverExtension'),
        ('DriverName.Length',        2, 0x38, 'uint16_t Length'),
        ('DriverName.MaximumLength', 2, 0x3a, 'uint16_t MaximumLength'),
        ('DriverName.Buffer',        8, 0x40, 'uint16_t* Buffer'),
        # UNICODE_STRING DriverName;
        ('HardwareDatabase',         8, 0x48, 'void* HardwareDatabase'),
        ('FastIoDispatch',           8, 0x50, 'void* FastIoDispatch'),
        ('DriverInit',               8, 0x58, 'void* DriverInit'),
        ('DriverStartIo',            8, 0x60, 'void* DriverStartIo'),
        ('DriverUnload',             8, 0x68, 'void* DriverUnload'),

        # void* MajorFunction[28];
        ('IRP_MJ_CREATE'              ,8, 0x70, 'void* IRP_MJ_CREATE'),
        ('IRP_MJ_CREATE_NAMED_PIPE'   ,8, 0x78, 'void* IRP_MJ_CREATE_NAMED_PIPE'),
        ('IRP_MJ_CLOSE'               ,8, 0x80, 'void* IRP_MJ_CLOSE'),
        ('IRP_MJ_READ'                ,8, 0x88, 'void* IRP_MJ_READ'),
        ('IRP_MJ_WRITE'               ,8, 0x90, 'void* IRP_MJ_WRITE'),
        ('IRP_MJ_QUERY_INFORMATION'   ,8, 0x98, 'void* IRP_MJ_QUERY_INFORMATION'),
        ('IRP_MJ_SET_INFORMATION'     ,8, 0xa0, 'void* IRP_MJ_SET_INFORMATION'),
        ('IRP_MJ_QUERY_EA'            ,8, 0xa8, 'void* IRP_MJ_QUERY_EA'),
        ('IRP_MJ_SET_EA'              ,8, 0xb0, 'void* IRP_MJ_SET_EA'),
        ('IRP_MJ_FLUSH_BUFFERS'       ,8, 0xb8, 'void* IRP_MJ_FLUSH_BUFFERS'),
        ('IRP_MJ_QUERY_VOLUME_INFORMATION' ,8, 0xc0, 'void* IRP_MJ_QUERY_VOLUME_INFORMATION'),
        ('IRP_MJ_SET_VOLUME_INFORMATION' ,8, 0xc8, 'void* IRP_MJ_SET_VOLUME_INFORMATION'),
        ('IRP_MJ_DIRECTORY_CONTROL'   ,8, 0xd0, 'void* IRP_MJ_DIRECTORY_CONTROL'),
        ('IRP_MJ_FILE_SYSTEM_CONTROL' ,8, 0xd8, 'void* IRP_MJ_FILE_SYSTEM_CONTROL'),
        ('IRP_MJ_DEVICE_CONTROL'      ,8, 0xe0, 'void* IRP_MJ_DEVICE_CONTROL'),
        ('IRP_MJ_INTERNAL_DEVICE_CONTROL' ,8, 0xe8, 'void* IRP_MJ_INTERNAL_DEVICE_CONTROL'),
        ('IRP_MJ_SHUTDOWN'            ,8, 0xf0, 'void* IRP_MJ_SHUTDOWN'),
        ('IRP_MJ_LOCK_CONTROL'        ,8, 0xf8, 'void* IRP_MJ_LOCK_CONTROL'),
        ('IRP_MJ_CLEANUP'             ,8, 0x100, 'void* IRP_MJ_CLEANUP'),
        ('IRP_MJ_CREATE_MAILSLOT'     ,8, 0x108, 'void* IRP_MJ_CREATE_MAILSLOT'),
        ('IRP_MJ_QUERY_SECURITY'      ,8, 0x110, 'void* IRP_MJ_QUERY_SECURITY'),
        ('IRP_MJ_SET_SECURITY'        ,8, 0x118, 'void* IRP_MJ_SET_SECURITY'),
        ('IRP_MJ_POWER'               ,8, 0x120, 'void* IRP_MJ_POWER'),
        ('IRP_MJ_SYSTEM_CONTROL'      ,8, 0x128, 'void* IRP_MJ_SYSTEM_CONTROL'),
        ('IRP_MJ_DEVICE_CHANGE'       ,8, 0x130, 'void* IRP_MJ_DEVICE_CHANGE'),
        ('IRP_MJ_QUERY_QUOTA'         ,8, 0x138, 'void* IRP_MJ_QUERY_QUOTA'),
        ('IRP_MJ_SET_QUOTA'           ,8, 0x140, 'void* IRP_MJ_SET_QUOTA'),
        ('IRP_MJ_PNP'                 ,8, 0x148, 'void* IRP_MJ_PNP')
        # void* MajorFunction[28];
    )

class IO_STACK_LOCATION(SymbolicStructureBase):
    _fields_ = (
        ('MajorFunction',      1, 0x00, 'uint8_t MajorFunction'),
        ('MinorFunction',      1, 0x01, 'uint8_t MinorFunction'),
        ('Flags',              1, 0x02, 'uint8_t Flags'),
        ('Control',            1, 0x03, 'uint8_t Control'),
        ('OutputBufferLength', 4, 0x08, 'uint32_t OutputBufferLength'),
        ('InputBufferLength',  4, 0x10, 'uint32_t InputBufferLength'),
        ('IoControlCode',      4, 0x18, 'uint32_t IoControlCode'),
        ('Type3InputBuffer',   8, 0x20, 'void* Type3InputBuffer'),
        ('DeviceObject',       8, 0x28, 'void* DeviceObject'),
        ('FileObject',         8, 0x30, 'void* FileObject'),
        ('CompletionRoutine',  8, 0x38, 'void* CompletionRoutine'),
        ('Context',            8, 0x40, 'void* Context'),
    )

class IRP(SymbolicStructureBase):
    _fields_ = (
        ('Type',                              2, 0x00, 'uint16_t Type'),
        ('Size',                              2, 0x02, 'uint16_t Size'),
        ('AllocationProcessorNumber',         2, 0x04, 'uint16_t AllocationProcessorNumber'),
        ('MdlAddress',                        8, 0x08, 'void* MdlAddress'),
        ('Flags',                             8, 0x10, 'uint64_t Flags'),
        ('AssociatedIrp.SystemBuffer',        8, 0x18, 'void* SystemBuffer'),
        ('IoStatus.Status',                   4, 0x30, 'uint32_t Status'),
        ('IoStatus.Information',              8, 0x38, 'uint64_t Information'),
        ('RequestorMode',                     1, 0x40, 'int8_t RequestorMode'),
        ('PendingReturned',                   1, 0x41, 'uint8_t PendingReturned'),
        ('StackCount',                        1, 0x42, 'int8_t StackCount'),
        ('CurrentLocation',                   1, 0x43, 'int8_t CurrentLocation'),
        ('Cancel',                            1, 0x44, 'uint8_t Cancel'),
        ('CancelIrql',                        1, 0x45, 'uint8_t CancelIrql'),
        ('ApcEnvironment',                    1, 0x46, 'int8_t ApcEnvironment'),
        ('AllocationFlags',                   1, 0x47, 'uint8_t AllocationFlags'),
        ('UserIosb',                          8, 0x48, 'void* UserIosb'),
        ('UserEvent',                         8, 0x58, 'void* UserEvent'),
        ('CancelRoutine',                     8, 0x58, 'void* CancelRoutine'),
        ('Tail.Overlay.CurrentStackLocation', 8, 0xb8, 'void* CurrentStackLocation'),
    )


import csv

class CSVReader:
    """Read CSV files

    Attributes:
        header: list of strings compromising the header row
        data: list of lists with parsed data
        file: string of file to be parsed
    """

    def __init__(self, filename):
        self.header = []
        self.data = []
        self.file = filename

    def readFile(self):
        """Reads file line by line, assigning values for header row and data

        Returns:
            list header: list of header values
            list data: list where each element is a row of data
        """
        csv_input = csv.reader(open(self.file, "rb"), skipinitialspace = True, delimiter = ",", quoting = csv.QUOTE_NONE)

        row_count = 0
        for row in csv_input:
            if row_count == 0:
                self.header = row
                self.data = [[] for _ in range(len(row))]
            else:
                for i in range(0, len(row)):
                    self.data[i].append(row[i])
            row_count += 1
        return self.header, self.data


import unittest
from collections import deque

def get_path(graph, start_node, end_node):

    # Find the shortest route in the network between the two users
    if start_node not in graph or end_node not in graph:
        raise Exception("Invalid params")

    q = deque()
    q.append(([], start_node))
    seen = set()
    while q:
        path, node = q.popleft()
        path.append(node)
        if node == end_node:
            return path

        seen.add(node)
        for neighbor in graph[node]:
            if neighbor not in seen:
                q.append((path[:], neighbor))
    return None

#     queue = deque()
#     visited = set()
#     if not graph or not start_node or not end_node:
#         return None
#     visited.add(start_node)
#     for neighbor in graph[start_node]:
#         queue.append(([start_node], neighbor))
#         visited.add(neighbor)
#     while queue:
#         current_route, node = queue.popleft()
#         current_route.append(node)
#         if node == end_node:
#             return current_route
#         else:
#             for neighbor in graph[node]:
#                 if neighbor not in visited:
#                     visited.add(neighbor)
#                     queue.append((current_route, neighbor))

#     return None

# def process_node(queue):

# Tests

class Test(unittest.TestCase):

    def setUp(self):
        self.graph = {
            'a': ['b', 'c', 'd'],
            'b': ['a', 'd'],
            'c': ['a', 'e'],
            'd': ['a', 'b'],
            'e': ['c'],
            'f': ['g'],
            'g': ['f'],
        }

    def test_two_hop_path_1(self):
        actual = get_path(self.graph, 'a', 'e')
        expected = ['a', 'c', 'e']
        self.assertEqual(actual, expected)

    def test_two_hop_path_2(self):
        actual = get_path(self.graph, 'd', 'c')
        expected = ['d', 'a', 'c']
        self.assertEqual(actual, expected)

    def test_one_hop_path_1(self):
        actual = get_path(self.graph, 'a', 'c')
        expected = ['a', 'c']
        self.assertEqual(actual, expected)

    def test_one_hop_path_2(self):
        actual = get_path(self.graph, 'f', 'g')
        expected = ['f', 'g']
        self.assertEqual(actual, expected)

    def test_one_hop_path_3(self):
        actual = get_path(self.graph, 'g', 'f')
        expected = ['g', 'f']
        self.assertEqual(actual, expected)

    def test_zero_hop_path(self):
        actual = get_path(self.graph, 'a', 'a')
        expected = ['a']
        self.assertEqual(actual, expected)

    def test_no_path(self):
        actual = get_path(self.graph, 'a', 'f')
        expected = None
        self.assertEqual(actual, expected)

    def test_start_node_not_present(self):
        with self.assertRaises(Exception):
            get_path(self.graph, 'h', 'a')

    def test_end_node_not_present(self):
        with self.assertRaises(Exception):
            get_path(self.graph, 'a', 'h')

unittest.main(verbosity=2)


import sqlite3
from flask_restful import Resource
import json
import pandas as pd
import controllers.db_constants as db_constants

class User():

    def __init__(self, _id, firstname, lastname, license_number, age, city):
        self.id = _id
        self.firstname = firstname
        self.lastname = lastname
        self.license_number = license_number
        self.age = age
        self.city = city

    @classmethod
    def find_by_license_number(cls, license_number):
        connection = sqlite3.connect('data.db')
        cursor = connection.cursor()
        query = "SELECT * FROM {table} WHERE license_number=?".format(table=db_constants.TABLE_NAME)
        result = cursor.execute(query, (license_number,))
        row = result.fetchone()
        if row:
            user = {}
            user['firstname'] = row[1]
            user['lastname'] = row[2]
            user['license_number'] = row[3]
            user['age'] = row[4]
            user['city'] = row[5]
        else:
            user = None

        connection.close()
        return user

class UserRegister(Resource):
    conn = None

    def check_database():
        ''' Check if the database exists or not '''
        try:
            print(f'Checking if {db_constants.DB_NAME} exists or not...')
            UserRegister.conn = sqlite3.connect(db_constants.DB_NAME, uri=True)
            print(f'Database exists. Succesfully connected to {db_constants.DB_NAME}')

        except sqlite3.OperationalError as err:
            print('Database does not exist')
            print(err)

    def create_database():
        connection = sqlite3.connect(db_constants.DB_NAME)
        cursor = connection.cursor()
        create_table = "CREATE TABLE IF NOT EXISTS {table} (id INTEGER PRIMARY KEY, firstname text, lastname text, license_number text, age int, city text)".format(table=db_constants.TABLE_NAME)
        cursor.execute(create_table)
        connection.commit()

    def upload_batch(filename):
        batch = pd.read_csv(filename)
        license_data = json.loads(batch.to_json(orient="records"))
        return license_data

    def insert_data(data):
        for row in data:

            if User.find_by_license_number(row['license_number']):
                return {"message": "User with that license_number already exists."}, 400

            connection = sqlite3.connect(db_constants.DB_NAME)
            cursor = connection.cursor()

            query = "INSERT INTO {table} VALUES (NULL, ?, ?, ?, ?, ?)".format(table=db_constants.TABLE_NAME)
            cursor.execute(query, (row['firstname'], row['lastname'], row['license_number'], row['age'], row['city']))

            connection.commit()
            connection.close()

    def post(filename):

        data = UserRegister.upload_batch(filename)
        if UserRegister.check_database():
            UserRegister.insert_data(data)
        else:
            UserRegister.create_database()
            UserRegister.insert_data(data)


import re
from tqdm import tqdm
import pickle
from datasets import load_dataset
from transformers import BertTokenizer
from nltk.tokenize import sent_tokenize, word_tokenize

def get_ngram(n, words):
    ngram_set = set()
    n_words = len(words)
    max_start_index = n_words - n
    for i in range(max_start_index + 1):
        ngram_set.add(tuple(words[i: i+n]))
    return ngram_set

def cal_rouge(src, ref):
    n_src = len(src)
    n_ref = len(ref)
    n_overlap = len(src.intersection(ref))

    if n_overlap == 0:
        p = 0.0
    else:
        p = n_overlap / n_src

    if n_ref == 0:
        r = 0.0
    else:
        r = n_overlap / n_ref

    f1_score = 2.0 * ((p * r) / (p + r + 1e-6))

    return f1_score

if __name__ == '__main__':
    dataset = load_dataset('cnn_dailymail', '3.0.0')
    print("dataset loaded")
    tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
    print("tokenizer loaded")

    preprocessed_dataset = []

    for row in tqdm(dataset['train']):
        _src = []
        src = row['article']
        src_sents = sent_tokenize(src)
        token_len = 0
        src_input_ids = []

        for sent in src_sents:
            cleand_sent = re.sub(r'[^a-zA-Z0-9 ]', '', sent)
            tokens = tokenizer(sent).input_ids
            if len(tokens) + token_len > 512:
                break
            src_input_ids.extend(tokens)
            token_len += len(tokens)
            _src.append(word_tokenize(cleand_sent))

        src_mask = [1] * token_len + [0] * (512-token_len)
        src_seg = [0] * 512
        src_tokens = {'input_ids':src_input_ids, 'token_type_ids':src_seg, 'attention_mask':src_mask}

        tgt = row['highlights']
        cleand_tgt = re.sub(r'[^a-zA-Z0-9 ]', '', tgt)
        _tgt = word_tokenize(cleand_tgt)
        tgt_tokens = tokenizer(cleand_tgt, max_length=512, padding="max_length")

        tgt_ngram_1 = get_ngram(1, _tgt)
        tgt_ngram_2 = get_ngram(2, _tgt)

        max_id = -1
        max_rouge = 0.0

        for i, _row in enumerate(_src):
            src_ngram_1 = get_ngram(1, _row)
            src_ngram_2 = get_ngram(2, _row)
            rouge_1 = cal_rouge(src_ngram_1, tgt_ngram_1)
            rouge_2 = cal_rouge(src_ngram_2, tgt_ngram_2)
            rouge_score = rouge_1 + rouge_2
            if rouge_score > max_rouge:
                max_rouge = rouge_score
                max_id = i

        clss = [i for i, token in enumerate(src_input_ids) if token == 101]
        tgt = clss[max_id]

        preprocessed_dataset.append({'src_tokens':src_tokens, 'clss':clss, 'tgt':tgt})

    with open('preprocessed_dataset', 'wb') as f:
        pickle.dump(preprocessed_dataset, f)


lista = []
conjunto = []
cont = 0
while True:
    lista.append(input('Nome do aluno: '))
    lista.append(float(input('Sua primeira nota: ')))
    lista.append(float(input('Sua segunda nota: ')))
    conjunto.append(lista[:])
    lista.clear()
    resp = input('Continuar? [S/N]: ').upper()[0]
    while resp not in 'SN':
        resp = input('Continuar? [S/N]: ').upper()[0]
    if resp in 'N':
        break
print('-------- BOLETIM --------')
for i in range(0, len(conjunto)):
    print(f'[{i}]    {conjunto[i][0]}    {((conjunto[i][1] + conjunto[i][2])/2):.1f}')
print('----------------')
while True:
    while True:
        nota = int(input('Faça a sua escolha [999 encerra]: '))
        if 0 <= nota <= len(conjunto) or nota == 999:
            break
    if 0 <= nota <= len(conjunto):
        print(f'Notas de {conjunto[nota][0]}: {conjunto[nota][1]}, {conjunto[nota][2]}')
    elif nota == 999:
        print('----------------')
        print('Fim')
        break


import pandas as pd
import numpy as np
import xlrd
import openpyxl

xlsx = pd.ExcelFile('Najpopularniejsze-imiona-w-Polsce-w-latach-2000-2017.xlsx') #zmiennej o nazwie xlsx przypisujemy plik (?!) rób wg tego schematu xD
df = pd.read_excel(xlsx, 'Arkusz1') #zmienna df przechowuje zawartośc naszego pliku o rozszerzeniu xmlx(nazwa zmiennej - w tym przypadku xlsx, nazwa arkusza)

# newdf = df[df['Liczba'] > 1000]
liczba_imion_wieksza_niz_1000 = df.query('Liczba > 1000') #do zmiennej przypisujemu zmienną df z warunkiem liczba większa od 1000
#print(liczba_imion_wieksza_niz_1000)

moje_imie = df.query(u"Imię == 'KLAUDIA'")
#print(moje_imie)

rok = 2007
rok_2007 = df.query('Rok == @rok')
# print(rok_2007)
liczba_dzieci = sum(rok_2007['Liczba'])
#print(liczba_dzieci)

rok_2000_2005 = df.query('Rok >= 2000 and Rok <= 2005')
licba_dziecii = sum(rok_2000_2005['Liczba'])
#print(licba_dziecii)
# print(rok_2000_2005)S
# print(df.iloc[10]['Rok']) wyświetlamy konkretną komórkę

chlopcy_i_dziewczynki = df.query(u"(Płeć) == 'M' and (Płeć) == 'K'")
liczba_chlopcow_i_dziewczynek = sum(chlopcy_i_dziewczynki['Liczba'])
#print(chlopcy_i_dziewczynki)

imiona_chlopca = df.query(u"Płeć == 'M' and Rok == 2002")
grouped = imiona_chlopca.sort_values(by='Liczba')
print(u"Najczęściej występujące imiona chłopca: ", grouped.iloc[0][u'Imię'], " i ",
      grouped.iloc[1][u"Imię"])
imiona_dziewczyny = df.query(u"Płeć == 'K' and Rok == 2004")
groupedk = imiona_dziewczyny.sort_values(by='Liczba')
print(u"Najczęściej występujące imiona dziewczynek z roku 2004: ", groupedk.iloc[0][u'Imię'], " i ",
      groupedk.iloc[1][u'Imię'])

# book = xlrd.open_workbook('Najpopularniejsze-imiona-w-Polsce-w-latach-2000-2017.xlsx')
# sh = book.sheet_by_name('Arkusz1')
#
# for i in range(sh.nrows):
#     print(sh.row(i))


class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

    def get_data(self):
        return self.data

    def get_next(self):
        return self.next

    def set_data(self, data):
        self.data = data

    def set_next(self, new_next):
        self.next = new_next

# Task 1
class UnorderedList:

    def __init__(self):
        self.head = None

    def is_empty(self):
        return self.head is None

    def add(self, item):
        temp = Node(item)
        temp.set_next(self.head)
        self.head = temp

    def size(self):
        current = self.head
        count = 0
        while current is not None:
            count += 1
            current = current.get_next()
        return count

    def search(self, item):
        current = self.head
        found = False
        while current is not None and not found:
            if current.get_data() == item:
                found = True
            else:
                current = current.get_next()
        return found

    def remove(self, item):
        current = self.head
        previous = None
        found = False
        while not found:
            if current.get_data() == item:
                found = True
            else:
                previous = current
                current = current.get_next()

        if previous is None:
            self.head = current.get_next()
        else:
            previous.set_next(current.get_next())

    def pop(self):
        current = self.head
        previous = None
        if current is None:
            return "No item in list"
        while current.get_next() is not None:
            previous = current
            current = current.get_next()
        previous.set_next(None)
        return current.get_data()

    def insert_of_position(self, pos, item):
        current = self.head
        previous = None
        index = 0
        temp = Node(item)
        while current is not None and index < pos:
            previous = current
            current = current.get_next()
            index += 1
        if pos == 0:
            temp.set_next(self.head)
            self.head = temp
        else:
            if current is None:
                previous.set_next(temp)
            else:
                temp.set_next(current)
                previous.setNext(temp)

    def delete_from_position(self, pos):
        current = self.head
        previous = None
        index = 0
        if current is None:
            return "No item in list"
        while index < pos and current is not None:
            previous = current
            current = current.get_next()
            index += 1
        if current is None:
            return "No item in list"
        else:
            if previous is None:
                self.head = current.get_next()
            else:
                previous.setNext(current.get_next())
            return current.get_data()

    def insert(self, item):
        current = self.head
        previous = None
        temp = Node(item)
        if current is None:
            previous.set_next(temp)
        temp.set_next(self.head)
        self.head = temp
        return current.get_data()

    def index(self, item):
        current = self.head
        found = False
        index = 0
        while current is not None and not found:
            if current.get_data() != item:
                index += 1
                current = current.get_next()
            else:
                found = True
        if found:
            return f'Element {item} has index {index}'
        else:
            return "Not Found"

    def generator_list(self):
        temp = self.head
        while temp is not None:
            yield temp.get_data()
            temp = temp.get_next()

    def slice(self, start=None, end=None):
        current = [i for i in self.generator_list()]
        if start is None or end is None:
            raise ValueError('Enter start and end')
        elif start < 0 or start > end or end > len(current)-1:
            raise ValueError('Wrong start or/and end')
        else:
            return current[start:end]

    def __repr__(self):
        representation = "<UnorderedList: "
        current = self.head
        while current is not None:
            representation += f"{current.get_data()} "
            current = current.get_next()
        return representation + ">"

# Task 2
class Stack:
    def __init__(self):
        self.head = None

    def is_empty(self):
        if self.head is None:
            return True
        else:
            return False

    def push(self, data):
        if self.head is None:
            self.head = Node(data)
        else:
            new_node = Node(data)
            new_node.next = self.head
            self.head = new_node

    def pop(self):
        if self.is_empty():
            return None
        else:
            popped_node = self.head
            self.head = self.head.next
            popped_node.next = None
            return popped_node.data

    def peek(self):
        if self.is_empty():
            return None
        else:
            return self.head.data

    def display(self):
        iter_node = self.head
        if self.is_empty():
            print("Stack Underflow")
        else:
            while iter_node is not None:
                print(iter_node.data, "->", end=" ")
                iter_node = iter_node.next
            return

    def __repr__(self):
        representation = "<Stack: "
        current = self.head
        while current is not None:
            representation += f"{current.data} "
            current = current.next
        return representation + ">"

# Task 3
class Queue:
    def __init__(self):
        self.front = self.rear = None

    def is_empty(self):
        return self.front is None

    def add_queue(self, item):
        temp = Node(item)

        if self.rear is None:
            self.front = self.rear = temp
            return
        self.rear.next = temp
        self.rear = temp

    def del_queue(self):

        if self.is_empty():
            return
        temp = self.front
        self.front = temp.next

        if self.front is None:
            self.rear = None

    def __repr__(self):
        representation = "<Queue: "
        current = self.front
        while current is not None:
            representation += f"{current.data} "
            current = current.next
        return representation + ">"

def main():
    my_list = UnorderedList()
    my_list.add(31)
    my_list.add(77)
    my_list.add(17)
    my_list.add(93)
    my_list.add(26)
    my_list.add(54)

    print(my_list.size())
    print(my_list)
    print(my_list.search(93))
    print(my_list.pop())
    print(my_list.insert(111))
    print(my_list.insert(103))
    print(my_list)
    print(my_list.pop())
    print(my_list)
    print(my_list.index(54))
    print(my_list.slice(2, 5))

########################################################################
    my_stack = Stack()
    my_stack.push(11)
    my_stack.push(22)
    my_stack.push(33)
    my_stack.push(44)
    print(my_stack)
    my_stack.display()
    print(f'\nTop element is {my_stack.peek()}')
    my_stack.pop()
    my_stack.pop()
    my_stack.display()
    print(f'\nTop element is {my_stack.peek()}')

########################################################
    q = Queue()
    q.add_queue(10)
    q.add_queue(20)
    q.add_queue(30)
    q.add_queue(40)
    q.add_queue(50)
    print(q)
    print(f'Queue Front: {q.front.data}')
    print(f'Queue Rear: {q.rear.data}')

if __name__ == '__main__':
    main()


from distutils.core import setup, Extension

opt = ['-Wall -Wuninitialized -Wstrict-prototypes -Wno-pointer-sign']

incdirs = ['../../include']

module1 = Extension('helios',
                    sources=['helios.c'],
                    include_dirs = incdirs,
                    libraries=["syscall"],
                    extra_compile_args = opt)

setup(  name = 'Helios',
        version = '0.1',
        author      = 'Guillaume ROGUEZ',
        description = 'Python module wrapper for the Helios library',
        ext_modules = [module1])


from plot import plt, sns, rescale_barplot_width
import pandas as pd
import argparse
import numpy as np
import metadata
import os
from collections import defaultdict

FONT_SIZE=20
plt.rcParams.update({
    "font.size": FONT_SIZE,
    "axes.labelsize" : FONT_SIZE,
    "font.size" : FONT_SIZE,
    "text.fontsize" : FONT_SIZE,
    "legend.fontsize": FONT_SIZE,
    "xtick.labelsize" : FONT_SIZE,
    "ytick.labelsize" : FONT_SIZE,
    })

def parse_args():
    parser = argparse.ArgumentParser(prog='graph', usage='%(prog)s [options]')
    parser.add_argument("cpu_scaling", help="benchmark data")
    parser.add_argument("http_scaling", help="benchmark data")
    return parser.parse_args()

def load_metrics(measurement):
    data = metadata.load(measurement)
    stats = defaultdict(list)
    for srv in data["services"]:
        df = pd.read_csv(os.path.join(measurement, srv["filename"]),
                sep="\t", index_col='time', parse_dates=True)
        if srv["name"] == "loadgenerator":
            name = "loadgenerator-requests_success_90_percentile"
            percentile = df[df[name].notnull()][name]
            index = percentile.index - percentile.index[0]
            stats["time"].extend(index)
            stats["requeusts_success_90%ile"].extend(percentile)
            stats["usage_percent"].extend([np.nan] * len(percentile))
            stats["service"].extend([srv["name"]] * len(percentile))
        else:
            assert "usage_percent" in df.columns
            usage_percent = df[df.usage_percent.notnull()].usage_percent
            index = usage_percent.index - usage_percent.index[0]
            stats["time"].extend(index)
            stats["usage_percent"].extend(usage_percent)
            stats["requeusts_success_90%ile"].extend([np.nan] * len(usage_percent))
            stats["service"].extend([srv["name"]] * len(usage_percent))
    where = os.path.join(measurement, data["autoscaling"]["filename"])
    df_scaling = pd.read_csv(where, sep="\t", index_col='time', parse_dates=True)
    df_scaling.index = df_scaling.index - df_scaling.index[0]
    df_cpu = pd.DataFrame(stats, index=stats["time"])
    return df_cpu.join(df_scaling, how="outer", lsuffix='', rsuffix='_scaling')

# Comparison of CPU utilisation of web service
# Comparison of SLA-violations
# Comparison of number of needed Scaling actions

def scaling(df):
    t = df[(df.service == "web") & df.scale.notnull()]
    return t[t.scale.diff() != 0]

def sla_violations(df):
    t = df[df["requeusts_success_90%ile"] > 1500]
    return t["requeusts_success_90%ile"].count()

USUAGE="CPU Usage"
SLA="SLA violations\\(out of 1400 samples)"
SCALING_ACTIONS="Number of\\ scaling actions"
A="Default metric"
B="Sieve metric"
C="Difference [%]"

def format_float(v):
    if v == int(v):
        return str(int(v))
    else:
        return "%.2f" % v

def main():
    args = parse_args()
    df_http = load_metrics(args.http_scaling)
    df_cpu  = load_metrics(args.cpu_scaling)

    scaling_cpu = scaling(df_cpu)
    scaling_http = scaling(df_http)

    usage_cpu = df_cpu[(df_cpu.service == "web") & df_cpu.usage_percent.notnull()]
    usage_http = df_http[(df_http.service == "web") & df_http.usage_percent.notnull()]
    requests_cpu = df_http[df_http["requeusts_success_90%ile"].notnull()]
    requests_http = df_cpu[df_cpu["requeusts_success_90%ile"].notnull()]

    graph = defaultdict(list) # type: defaultdict[str, List]
    def append_metric(name, before, after):
        graph["metric"].append(name)
        graph[A].append(before)
        graph[B].append(after)
        graph[C].append((after - before)/before * 100)
    append_metric(USUAGE, usage_cpu.usage_percent.mean(), usage_http.usage_percent.mean())
    append_metric(SLA, sla_violations(requests_cpu), sla_violations(requests_http))
    append_metric(SCALING_ACTIONS, scaling_cpu.scale.count(), scaling_http.scale.count())
    df = pd.DataFrame(graph)
    df = df[["metric", A, B, C]].set_index("metric")
    table = df.to_latex(float_format=format_float, formatters={C: lambda v: ("+" if v > 0 else "") + format_float(v)})
    print(table)

if __name__ == "__main__":
    main()


import matplotlib.pyplot as plt
import numpy as np

IXY4 = []
IXY8 = []
IXZ4 = []
IXZ8 = []
IXZbar_4 = []
IXZbar_8 = []
IXZbar15_4 = []
IXZbar15_8 = []
SNR = np.arange(-20, 31, 1)
with open("IXY4.txt") as file1:
    lines = file1.readlines()
    ixy4 = [line.split()[0] for line in lines]

with open("IXY8.txt") as file1:
    lines = file1.readlines()
    ixy8 = [line.split()[0] for line in lines]

with open("IXZ4.txt") as file1:
    lines = file1.readlines()
    ixz4 = [line.split()[0] for line in lines]

with open("IXZ8.txt") as file1:
    lines = file1.readlines()
    ixz8 = [line.split()[0] for line in lines]

with open("IXZbar_4.txt") as file1:
    lines = file1.readlines()
    ixzbar_4 = [line.split()[0] for line in lines]

with open("IXZbar_8.txt") as file1:
    lines = file1.readlines()
    ixzbar_8 = [line.split()[0] for line in lines]

with open("IXZbar_154.txt") as file1:
    lines = file1.readlines()
    ixzbar15_4 = [line.split()[0] for line in lines]

with open("IXZbar_158.txt") as file1:
    lines = file1.readlines()
    ixzbar15_8 = [line.split()[0] for line in lines]

for i in ixy4:
    IXY4.append(float(i))

for i in ixy8:
    IXY8.append(float(i))

for i in ixz4:
    IXZ4.append(float(i))

for i in ixz8:
    IXZ8.append(float(i))

for i in ixzbar_4:
    IXZbar_4.append(float(i))

for i in ixzbar_8:
    IXZbar_8.append(float(i))

for i in ixzbar15_4:
    IXZbar15_4.append(float(i))

for i in ixzbar15_8:
    IXZbar15_8.append(float(i))

# plt.plot(SNR, IXY4, label="I(x;y), 4-ASK")
# plt.plot(SNR, IXZ4, label="I(x;z), 4-ASK")
# plt.plot(SNR, IXZbar_4, label="I(x;ẑ), 4-ASK TX-SNR = 20 dB")
# plt.plot(SNR, IXZbar15_4, label="I(x;ẑ), 4-ASK TX-SNR = 15 dB")
plt.plot(SNR, IXY8, label="I(x;y), 8-ASK")
plt.plot(SNR, IXZ8, label="I(x;z), 8-ASK")
plt.plot(SNR, IXZbar_8, label="I(x;ẑ), 8-ASK TX-SNR = 20 dB")
plt.plot(SNR, IXZbar15_8, label="I(x;ẑ), 8-ASK TX-SNR = 15 dB")
plt.xlabel('SNR (dB)')
plt.title('Effect of Quantization and Transmission')
plt.ylabel('Mutual Information')
plt.xticks(np.arange(-20, 32, 5))
plt.legend()
plt.grid()
plt.show()


import pytest
from sokoban import World

SIMPLE_LEVEL = [
    "#########",
    "#.$ @   #",
    "#########",
]

def test_rect_world_dimensions():
    world = World(SIMPLE_LEVEL)

    assert world.nrows == 3
    assert world.ncols == 9

def test_worker_pos():
    world = World(SIMPLE_LEVEL)
    assert world.worker_pos == [(4, 1)]

def test_single_box_dock():
    world = World(SIMPLE_LEVEL)

    assert world.box_pos == [(2, 1)]
    assert world.dock_pos == [(1, 1)]

LARGE_LEVEL = [
    "######## ",
    "#.$ @  ##",
    "#.$     #",
    "#########",
]

def test_nonrect_world_dimenions():
    world = World(LARGE_LEVEL)
    assert world.nrows == 4
    assert world.ncols == 9

def test_multiple_box_dock():
    world = World(LARGE_LEVEL)
    assert world.box_pos == [(2, 1), (2, 2)]
    assert world.dock_pos == [(1, 1), (1, 2)]

### START: test1.py
def test_invalid_character_error():
    level = [
        "########!",
        "#.$     #",
        "#########",
    ]

    pytest.raises(ValueError, World, level)
### END: test1.py

### START: test2.py
def test_invalid_character_error():
    level = [
        "########!",
        "#.$     #",
        "#########",
    ]

    excinfo = pytest.raises(ValueError, World, level)
    assert excinfo.match("character")
### END: test2.py

### START: test3.py
def test_no_worker_error():
    level = [
        "#########",
        "#.$     #",
        "#########",
    ]
    excinfo = pytest.raises(ValueError, World, level)
    assert excinfo.match("worker")
### END: test3.py


"""
---------------------------------------------------
This code is part of the AISTATS 2021 submission:
>>> Marienwald, Hannah, Fermanian, Jean-Baptiste & Blanchard, Gilles.
    "High-Dimensional Multi-Task Averaging and Application to Kernel
    Mean Embedding." In International Conference on Artificial
    Intelligence and Statistics. PMLR, 2021. <<<
---------------------------------------------------
WINE_settings.py:
    Sets the settings of the experiment.
"""

### update as desired ########################################################
unbiased    = True       # unbiased estimation of the MMD^2
replace     = True       # replace negative values of MMD^2 with zero
save_neighs = True       # save the number of neighbors
use_mdnf    = True       # use MDNF (or DNF) kernel
subsample_size  = 50     # number of observations used to estimate the KMEs
num_trials      = 100    # number of trials (repetitions of experiments)
T_full  = 15             # number of bags (all)
T_train = T_full - 1     # number of bags used for training
T_test  = 1              # number of bags used for testing

# where to store the results
str_samples = str(subsample_size)+'_samples/'
if use_mdnf:
    str_kernel  = 'mDNF_Kernel/'
else:
    str_kernel  = 'DNF_Kernel/'
FN = '../Results/wine_kme/'+str_samples+str_kernel+'TrialData/'
FN_Datapath  = '../Results/wine_kme/Data/'  # where the raw data set is saved
FN_X     = FN_Datapath+'X.mat'              # where the used data is saved
##############################################################################


from typing import List

class MessagePacket(object):
    CESAR_DEFAULT_DEVICE_NUMBER = 1
    MAX_DATA_LENGTH = 0b111

    def __init__(self, binary_data: bytearray = None, cesar_device_number=None):

        self._raw = binary_data

        self._header = 0
        self._checksum = 0
        self._command_id = 0
        self._optional_length = 0
        self._data = []

        self._address = 0
        self._data_length = 0
        self._intArray = []

        if cesar_device_number is None:
            cesar_device_number = self.CESAR_DEFAULT_DEVICE_NUMBER

        self._device_id = cesar_device_number

        # create all instances out of binary data if present
        if self._raw:
            self.parse_packet(binary_data)

    @classmethod
    def from_raw(cls, binary_data):
        return cls(binary_data)

    def get_header(self):
        return self._header

    def set_address(self, address):
        if not 0 <= address <= 0b11111:
            raise ValueError("Given address is invalid")

        self._address = address

    def set_data(self, data: bytearray):
        if len(data) > 255:
            raise ValueError("Cannot send more than 255 data bytes")

        self._data = data

    def set_command(self, command_id):
        if not 0 <= command_id <= 255:
            raise ValueError("Invalid command id given")

        self._command_id = command_id

    def get_data(self):
        return self._data

    def get_data_length(self):
        return len(self._data)

    def is_valid(self):
        return self._checksum == self.xor(self._intArray)

    def to_raw(self):
        data_length = len(self._data)

        header_data_length = data_length
        optional_length = None

        if data_length > 0b111:
            header_data_length = 0b111
            optional_length = data_length

        # The header looks like this (in binary)
        #
        #   xxxxx yyy
        #
        # where the first 5 x (five bit) correspond to the serial number
        # and the last 3 y (three bit) correspond to the data length
        header = (self._address << 3) | header_data_length

        raw = [header, self._command_id, optional_length] + self._data

        # remove the optional length byte if it is None
        raw = [el for el in raw if el is not None]

        checksum = self.xor(raw)

        return raw + [checksum]

    @staticmethod
    def from_raw(raw: bytearray):
        return MessagePacket(raw)

    def parse_packet(self, raw: bytearray):
        data = raw.copy()

        self._header = data.pop(0)

        self._address = self._header >> 3
        self._data_length = self._header & self.MAX_DATA_LENGTH

        self._command_id = data.pop(0)  # command number from 0-255

        # if more than 6 Data bytes, the data contains an optional length byte
        # maximum bytes left when no optional length string needed are 7
        if len(data) > 7:
            self._optional_length = data.pop(0)

        self._checksum = data.pop()
        # need for list comprehension in order to store self._data as an int list and not a bytearray
        self._data = [k for k in data]

        self.createIntArray()

    def create_header(self, datalength, serialnumber=None):
        if datalength > self.MAX_DATA_LENGTH:
            raise RuntimeError("Given data length exceeds the maximum data length")

        if serialnumber is None:
            serialnumber = self.CESAR_DEFAULT_DEVICE_NUMBER

        self._header = (serialnumber << 3) | datalength

    @staticmethod
    def xor(raw: bytearray):
        result = 0

        for data in raw:
            result = int(data) ^ result

        return result

    def compute_checksum(self, raw: List[int] = None):

        if raw is None:
            raw = self._intArray

        self._checksum = self.xor(raw)
        self._intArray.append(self._checksum)

    def createIntArray(self):
        # all components need to exist before calling this function
        # self._intArray contains no checksum
        self._intArray = [self._header, self._command_id]
        if self._data_length > 6:
            self._intArray.append(self._optional_length)
        if self._data_length != 0:
            self._intArray += self._data

    def createMessagePacket(self, cmd_id, data_length, data=None):
        self._command_id = cmd_id
        self._data_length = data_length

        if data is not None:
            # temp = bytearray(data.to_bytes(self._data_length, "little"))
            self._data = [k for k in data]

            if self._data_length > 6:
                self._optional_length = self._data_length
                self.create_header(7, self._device_id)

        if self._data_length < 7:
            self.create_header(self._data_length, self._device_id)

        self.assembleMessagePacket()
        return self.ByteArray

    def assembleMessagePacket(self):
        self.createIntArray()
        self.compute_checksum()
        self.ByteArray = bytearray(self._intArray)


from itertools import combinations
from collections import Counter

def solution(orders, course):
    ans = []
    for i in course:
        all_menus = dict()
        for order in orders:
            menus = combinations(order, i)
            for menu in menus:
                menu = ''.join(sorted(menu))
                if menu not in all_menus:
                    all_menus[menu] = 1
                else:
                    all_menus[menu] += 1

        candidates = Counter(all_menus).most_common()
        ans += [menu for menu, cnt in candidates if cnt > 1 and cnt == candidates[0][1]]

    return sorted(ans)

print(solution(["XYZ", "XWY", "WXA"], [2,3,4]))


def Solution(S):
    count = {}
    for s in S:
      if s in count:
        count[s] += 1
      else:
        count[s] = 1

    for key in count:
      if count[key] > 1:
        return key

print(Solution("zz"))


import requests
from bs4 import BeautifulSoup
import re
from urllib.parse import urlparse, urljoin

R = '\033[31m'  # red
G = '\033[32m'  # green
C = '\033[36m'  # cyan
W = '\033[0m'   # white
Y = '\033[33m'  # yellow

def perform_web_recon(website_url):
    # Set timeout values in seconds
    timeout = 10

    # Send a GET request to the website
    response = requests.get(website_url, timeout=timeout)

    # Check if the request was successful
    if response.status_code == 200:
        # Parse the HTML content using BeautifulSoup
        soup = BeautifulSoup(response.content, 'html.parser')

        # Lists to store URLs of different types of files
        js_files = []
        css_files = []
        html_files = []
        php_files = []
        image_files = []
        internal_links = set()
        external_links = set()

        # Regular expression pattern to match file extensions
        file_extension_pattern = r'\.([a-zA-Z0-9]+)$'

        # Find all <script> tags and extract src URLs
        for script_tag in soup.find_all('script', src=True):
            src = script_tag['src']
            js_files.append(src)

        # Find all <link> tags with rel="stylesheet" and extract href URLs
        for link_tag in soup.find_all('link', rel='stylesheet', href=True):
            href = link_tag['href']
            css_files.append(href)

        # Find all <a> tags and extract href URLs
        for a_tag in soup.find_all('a', href=True):
            href = a_tag['href']
            if re.search(file_extension_pattern, href):
                extension = re.search(file_extension_pattern, href).group(1)
                if extension == 'html':
                    html_files.append(href)
                elif extension == 'php':
                    php_files.append(href)
                else:
                    image_files.append(href)
            else:
                if href.startswith('#'):
                    continue
                full_url = urljoin(website_url, href)
                parsed_url = urlparse(full_url)
                if parsed_url.netloc == urlparse(website_url).netloc:
                    internal_links.add(full_url)
                else:
                    external_links.add(full_url)

        # Print the URLs
        print(f"{G}╰➤ {C}JS Files:{W}")
        for js_file in js_files:
            print(js_file)

        print(f"\n{G}╰➤ {C}CSS Files:{W}")
        for css_file in css_files:
            print(css_file)

        print(f"\n{G}╰➤ {C}HTML Files:{W}")
        for html_file in html_files:
            print(html_file)

        print(f"\n{G}╰➤ {C}PHP Files:{W}")
        for php_file in php_files:
            print(php_file)

        print(f"\n{G}╰➤ {C}Image Files:{W}")
        for image_file in image_files:
            print(image_file)

        print(f"\n{G}╰➤ {C}Internal Links:{W}")
        for internal_link in internal_links:
            print(internal_link)

        print(f"\n{G}╰➤ {C}External Links:{W}")
        for external_link in external_links:
            print(external_link)

        # Directory search and print details
        directory_search = website_url + "/directory"  # Replace with the directory you want to search
        directory_response = requests.get(directory_search, timeout=timeout)

        if directory_response.status_code == 200:
            directory_soup = BeautifulSoup(directory_response.content, 'html.parser')
            directory_links = []

            # Find all <a> tags in the directory page
            for a_tag in directory_soup.find_all('a', href=True):
                href = a_tag['href']
                full_url = urljoin(directory_search, href)
                directory_links.append(full_url)

            print("\nDirectory Links:")
            for directory_link in directory_links:
                print(directory_link)

        else:
            print("\nFailed to fetch directory. Status code:", directory_response.status_code)

        # Print the counts
        print(f"\n{G}╰➤ {C}Total JS Files:{W}", len(js_files))
        print(f"{G}╰➤ {C}Total CSS Files:{W}", len(css_files))
        print(f"{G}╰➤ {C}Total HTML Files:{W}", len(html_files))
        print(f"{G}╰➤ {C}Total PHP Files:{W}", len(php_files))
        print(f"{G}╰➤ {C}Total Image Files:{W}", len(image_files))
        print(f"{G}╰➤ {C}Total Internal Links:{W}", len(internal_links))
        print(f"{G}╰➤ {C}Total External Links:{W}", len(external_links))

    else:
        print(f"{R}Failed to fetch the website. Status code:", response.status_code)

if __name__ == "__main__":
    target_website = "https://spyboy.blog"  # Replace with your desired URL
    perform_web_recon(target_website)


from selenium import webdriver

chrome_driver_path = "/Users/loaialebdi/Dev/Python_MiniProjects/seleniumToDict/chromedriver"
driver = webdriver.Chrome(executable_path=chrome_driver_path)

driver.get("https://www.python.org/")
event_times = driver.find_elements_by_css_selector(".event-widget time")
event_names = driver.find_elements_by_css_selector(".event-widget li a")
events = {}

for n in range(len(event_times)):
    events[n] = {
        "time": event_times[n].text,
        "name": event_names[n].text
    }

print(events)

# for time in event_times:
#     print(time.text)

# for name in event_names:
#     print(name.text)

driver.close()


# coding: utf-8

from __future__ import absolute_import
from datetime import date, datetime  # noqa: F401

from typing import List, Dict  # noqa: F401

from app.openapi_server.models.base_model_ import Model
from app.openapi_server.models.favorite_impllinks import FavoriteImpllinks  # noqa: F401,E501
from app.openapi_server.models.pipeline_impl import PipelineImpl  # noqa: F401,E501
from openapi_server import util

class FavoriteImpl(Model):
    """NOTE: This class is auto generated by the swagger code generator program.

    Do not edit the class manually.
    """

    def __init__(self, _class: str=None, links: FavoriteImpllinks=None, item: PipelineImpl=None):  # noqa: E501
        """FavoriteImpl - a model defined in Swagger

        :param _class: The _class of this FavoriteImpl.  # noqa: E501
        :type _class: str
        :param links: The links of this FavoriteImpl.  # noqa: E501
        :type links: FavoriteImpllinks
        :param item: The item of this FavoriteImpl.  # noqa: E501
        :type item: PipelineImpl
        """
        self.swagger_types = {
            '_class': str,
            'links': FavoriteImpllinks,
            'item': PipelineImpl
        }

        self.attribute_map = {
            '_class': '_class',
            'links': '_links',
            'item': 'item'
        }

        self.__class = _class
        self._links = links
        self._item = item

    @classmethod
    def from_dict(cls, dikt) -> 'FavoriteImpl':
        """Returns the dict as a model

        :param dikt: A dict.
        :type: dict
        :return: The FavoriteImpl of this FavoriteImpl.  # noqa: E501
        :rtype: FavoriteImpl
        """
        return util.deserialize_model(dikt, cls)

    @property
    def _class(self) -> str:
        """Gets the _class of this FavoriteImpl.

        :return: The _class of this FavoriteImpl.
        :rtype: str
        """
        return self.__class

    @_class.setter
    def _class(self, _class: str):
        """Sets the _class of this FavoriteImpl.

        :param _class: The _class of this FavoriteImpl.
        :type _class: str
        """

        self.__class = _class

    @property
    def links(self) -> FavoriteImpllinks:
        """Gets the links of this FavoriteImpl.

        :return: The links of this FavoriteImpl.
        :rtype: FavoriteImpllinks
        """
        return self._links

    @links.setter
    def links(self, links: FavoriteImpllinks):
        """Sets the links of this FavoriteImpl.

        :param links: The links of this FavoriteImpl.
        :type links: FavoriteImpllinks
        """

        self._links = links

    @property
    def item(self) -> PipelineImpl:
        """Gets the item of this FavoriteImpl.

        :return: The item of this FavoriteImpl.
        :rtype: PipelineImpl
        """
        return self._item

    @item.setter
    def item(self, item: PipelineImpl):
        """Sets the item of this FavoriteImpl.

        :param item: The item of this FavoriteImpl.
        :type item: PipelineImpl
        """

        self._item = item


# File: state.py
# Class file for the state
# Includes two classes
# - Config (default configuration for the state)
# - State (contains the current state and possible actions on the state)

import csv
import ast
import numpy as np
from . import Config, State
from . import ChaosState
from . import ChainState

class StateReader(object):
    """Read config and state files"""
    def __init__(self, file_name=None):
        # initialize
        self.default_file_name = 'state.csv' if file_name is None else file_name

    def write_state(self, state, file_name=None):
        """Read a state file"""

        if isinstance(state, State):
            self.write_game_state(state, file_name)
        else:
            self.write_step_state(state, file_name)

    def read_state(self, file_name=None, default_reward_matrix=None):
        """Read a state file"""

        # revert to the default file
        if file_name is None:
            file_name = self.default_file_name

        # read from the given file
        state_type = -1
        with open(file_name, 'r') as csvfile:
            reader = csv.reader(csvfile, delimiter=';', quotechar='"', quoting=csv.QUOTE_MINIMAL)
            state_type = next(reader)

        # read the file as per the state_type
        if int(state_type[0]) == 0 or int(state_type[0]) == 1:
            return self.read_game_state(file_name, default_reward_matrix)
        else:
            return self.read_step_state(file_name, default_reward_matrix)

    def write_game_state(self, state, file_name=None):
        """Read a state file"""

        # revert to the default file
        if file_name is None:
            file_name = self.default_file_name

        # write to the defined config file
        with open(file_name, 'w') as csvfile:
            writer = csv.writer(csvfile, delimiter=';', quotechar='"', quoting=csv.QUOTE_MINIMAL)
            writer.writerow([1 if isinstance(state, ChaosState) else 0])
            writer.writerow([state.config.num_service])
            writer.writerow([state.config.num_viruses])
            writer.writerow([state.config.num_datadir])
            writer.writerow([state.config.num_nodes])

            writer.writerow([state.config.sparcity])
            writer.writerow([state.config.server_client_ratio])
            writer.writerow(state.config.ratios)

            writer.writerow(state.config.low_value_nodes)
            writer.writerow(state.config.high_value_nodes)

            writer.writerow([state.config.att_points])
            writer.writerow([state.config.def_points])
            writer.writerow(state.config.att_cost_weights)
            writer.writerow(state.config.def_cost_weights)

            writer.writerow(state.config.scalarization)

            writer.writerow(state.nn_input)
            writer.writerow(state.graph_edges)
            writer.writerow(state.graph_weights)
            if state.reward_matrix is not None:
                writer.writerow(state.reward_matrix.tolist())
            else:
                writer.writerow([0])

    def write_step_state(self, state, file_name=None):
        """Read a state file"""

        # revert to the default file
        if file_name is None:
            file_name = self.default_file_name

        # write to the defined config file
        with open(file_name, 'w') as csvfile:
            writer = csv.writer(csvfile, delimiter=';', quotechar='"', quoting=csv.QUOTE_MINIMAL)
            writer.writerow([2])
            writer.writerow([state.config.size_def_strategies])
            writer.writerow([state.config.size_att_strategies])
            writer.writerow([state.config.num_nodes])
            writer.writerow([state.config.max_lfr])
            writer.writerow([state.config.alpha])
            writer.writerow([state.config.beta])

            writer.writerow(state.config.cap_values)
            writer.writerow(state.nodes_con)
            writer.writerow(state.nodes_cap)
            writer.writerow(state.nodes_acc)
            writer.writerow(state.edges_lfr)
            writer.writerow(state.edges_sco)
            writer.writerow(state.strat_def)

            writer.writerow(state.strat_att_chain)
            writer.writerow(state.strat_att_conn)

    def read_game_state(self, file_name=None, default_reward_matrix=None):
        """Read a state file"""

        # basic variables
        config = Config()
        state = None
        content = None

        # revert to the default file
        if file_name is None:
            file_name = self.default_file_name

        # read from the defined config file
        with open(file_name, 'r') as csvfile:
            reader = csv.reader(csvfile, delimiter=';', quotechar='"', quoting=csv.QUOTE_MINIMAL)
            content = list(reader)

        if isinstance(content, list) and len(content) == 19:
            is_basic_state = (int(content[0][0]) == 0)
            config.num_service = int(content[1][0])
            config.num_viruses = int(content[2][0])
            config.num_datadir = int(content[3][0])
            config.num_nodes = int(content[4][0])

            config.sparcity = float(content[5][0])
            config.server_client_ratio = float(content[6][0])
            config.ratios = np.array(content[7], dtype=np.int)

            config.low_value_nodes = self.__list_of_list_from_string_list(content[8])
            config.high_value_nodes = self.__list_of_list_from_string_list(content[9])

            config.att_points = int(content[10][0])
            config.def_points = int(content[11][0])
            config.att_cost_weights = np.array(content[12], dtype=np.int)
            config.def_cost_weights = np.array(content[13], dtype=np.int)

            config.scalarization = np.array(content[14], dtype=np.int)

            default_input = np.array(content[15], dtype=np.int)
            default_edges = self.__list_of_list_from_string_list(content[16])
            default_graph_weights = np.array(content[17], dtype=np.int)

            if default_reward_matrix is None and not is_basic_state:
                intial_list = self.__list_of_list_from_string_list(content[18])
                default_reward_matrix = np.array(intial_list)

            if is_basic_state:
                state = State(config, default_input, default_edges, default_graph_weights)
            else:
                state = ChaosState(config, default_input, default_edges, default_graph_weights, default_reward_matrix)

        else:
            print("Could not read config file.")

        return state

    def read_step_state(self, file_name=None, default_reward_matrix=None):
        """Read a state file"""

        # basic variables
        config = Config()
        state = None
        content = None

        # revert to the default file
        if file_name is None:
            file_name = self.default_file_name

        # read from the defined config file
        with open(file_name, 'r') as csvfile:
            reader = csv.reader(csvfile, delimiter=';', quotechar='"', quoting=csv.QUOTE_MINIMAL)
            content = list(reader)

        if isinstance(content, list):
            is_chain_state = (int(content[0][0]) == 2)
            config.size_def_strategies = int(content[1][0])
            config.size_att_strategies = int(content[2][0])
            config.num_nodes = int(content[3][0])
            config.max_lfr = float(content[4][0])
            config.alpha = float(content[5][0])
            config.beta = float(content[6][0])
            config.cap_values = self.__list_of_list_from_string_list(content[7])

            if is_chain_state:
                state = ChainState(config)
                state.nodes_con = np.array(self.__list_of_list_from_string_list(content[8]), dtype=np.int)
                state.nodes_cap = np.array(self.__list_of_list_from_string_list(content[9]), dtype=np.int)
                state.nodes_acc = np.array(self.__list_of_list_from_string_list(content[10]), dtype=np.int)
                state.edges_lfr = np.array(self.__list_of_list_from_string_list(content[11]), dtype=float)
                state.edges_sco = np.array(self.__list_of_list_from_string_list(content[12]), dtype=np.int)
                state.strat_def = np.array(self.__list_of_list_from_string_list(content[13]), dtype=np.int)

                state.strat_att_chain = self.__list_of_list_from_string_list(content[14])
                state.strat_att_conn = self.__list_of_np_arrays_from_string_list(content[15])
                state.calculate_defense()
                state.calculate_results()

        else:
            print("Could not read config file.")

        return state

    def __list_of_list_from_string_list(self, input_list):
        """Convert a single list with strings to a list of lists"""
        output_list = []
        for item in input_list:
            output_list.append(ast.literal_eval(item))

        return output_list

    def __list_of_np_arrays_from_string_list(self, input_list):
        """Convert a single list with strings to a list of lists"""
        output_list = []
        for item in input_list:
            # create a numpy array from the item
            actual = list(filter(len, item[1:-1].split(' ')))
            conn_down = np.zeros(len(actual), dtype=np.int)
            for i in range(len(conn_down)):
                conn_down[i] = actual[i]

            # add the array to the list
            output_list.append(conn_down)

        return output_list


from __future__ import print_function
import sys, os
from .. util.debug_tools import*
from .. Visu.init.fticrvisuUi import Ui_MainWindow as Ui
from .. Visu.init.fticrvisupopUi import Ui_Form as Pop
from .. Visu.Pyside_PyQt4 import*
import unittest

@dec_class_pr
@decclassdebugging
class INTERFACE(): #interface
    '''
    Creation of the graphic window
    Methods :
        init_interf
        makelayout
        makecanvas
        clearlayout
        run
    '''
    def __init__(self):
        '''
        Two ways for launching Qt application, normal way and Canopy way.
        '''
        print("in INTERFACE")
        try:
            whichapp =  'app is QtGui.QApplication(sys.argv)'
            self.app = QtGui.QApplication(sys.argv)
        except :
            whichapp = 'app is QtCore.QCoreApplication.instance()'
            self.app = QtCore.QCoreApplication.instance() # Correction for Canopy
        #print whichapp
        self.window = QtGui.QMainWindow()
        self.ui = Ui()#
        self.ui.setupUi(self.window) # Set up of the main window
        #self.show_toolbar = False
        self.init_interf()

    def init_interf(self):
        '''
        Initialization of the interface
        '''
        self.window.setCursor(QtCore.Qt.ArrowCursor)
        self.makelayout()

    def makelayout(self):
        '''
        make the layout in the centralwidget
        '''
        print("makes and fills the layout")
        self.ui.layoutC = QtGui.QVBoxLayout(self.ui.centralwidget)   # Create the layout widget.
        self.ui.layoutC.setContentsMargins(280, 50, 10, 70)          # Margin for the picture left, up, right, bottom

    def clearlayout(self, layout):                                   # Delete item widgets in the layout to allow the refresh.
        '''
        Clear the layout of the centralwidget
        '''
        if debug(self): print("in interface.clearlayout")
        while layout.count() > 0:
            item = layout.takeAt(0)
            if not item: continue
            w = item.widget()
            if w: w.deleteLater()

    def run(self):
        self.window.show()
        sys.exit(self.app.exec_()) # Correction for Canopy

class interfaceTests(unittest.TestCase):

    def test_interface(self):
        "Testing interface module"
        interf = INTERFACE()
        self.assertIsInstance(interf.window, QtGui.QMainWindow)
        self.assertIsInstance(interf.ui, Ui)
        self.assertIsInstance(interf.ui.layoutC, QtGui.QVBoxLayout)

if __name__ == '__main__':
    unittest.main()


"""
Vues de l'application "Research", permettant de traiter toutes
les requêtes liées à la recherche de produits
"""
from django.shortcuts import render, redirect, HttpResponseRedirect, get_object_or_404, HttpResponse
from django.core.paginator import Paginator
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.db import IntegrityError
from .models import Product, Substitute, Rating
from .manager import manager_display_products
from .forms import RatingForm

@login_required
def display_substitutes(request):
    """
    Fonction permettant d'afficher les substituts
    enregistrés d'un utilisateur.
    La balise @login_required permet de n'afficher
    cette page que si l'utilisateur est connecté.
    """
    substitutes = Substitute.objects.filter(user=request.user)
    products_paginator = Paginator(substitutes, 6)
    page_number = request.GET.get("page")
    page = products_paginator.get_page(page_number)
    if User.is_authenticated:
        return render(request, "research/substitutes.html", {'count':products_paginator.count, "page":page})
    else:
        return redirect("frontpage")

def display_products(request):
    """
    Fonction permettant d'afficher les substituts
    enregistrés d'un utilisateur.
    La balise @login_required permet de n'afficher
    cette page que si l'utilisateur est connecté.
    """
    if request.method == "GET":
        try:
            search = request.GET.get("search")
            page_number = request.GET.get("page")
            data = manager_display_products(search, page_number)
            return render(request, "research/products.html", data)
        except ValueError:
            return redirect("frontpage")

def product_details(request, product_pk):
    """
    Fonction permettant d'afficher les détails
    d'un produit sur une page dédiée.
    """
    try:
        user = request.user
    except TypeError:
        pass

    product = get_object_or_404(Product, pk=product_pk)
    values = Rating.objects.filter(product=product).values('note')
    users = Rating.objects.filter(product=product).values('user_id')

    try:
        exists = Rating.objects.get(product=product, user=user)
        hasVoted = True
    except Rating.DoesNotExist:
        hasVoted = False
    except TypeError:
        hasVoted = False

    form = RatingForm()
    if values:
        final_note = 0
        count = 0
        for value in values:
            final_note += value["note"]
            count += 1
        _rating = final_note / count

        return render(request, "research/product.html", {"product":product, "rating":_rating, "hasVoted":hasVoted, "form":form})
    else:
        return render(request, "research/product.html", {"product":product, "hasVoted":hasVoted, "form":form})

@login_required
def save_product(request, product_pk):
    """
    Fonction permettant d'enregistrer un produit
    en substitut pour un utilisateur.
    La balise @login_required permet de n'afficher
    cette page que si l'utilisateur est connecté.
    """
    if request.method == "POST":
        product = get_object_or_404(Product, pk=product_pk)
        user = request.user
        substitute = Substitute(product=product, user=user)
        substitute.save()
        return redirect("substitutes")
    else:
        return redirect("frontpage")

@login_required
def delete_product(request, substitute_pk):
    """
    Fonction permettant de supprimer un substituts
    des enregistrés d'un utilisateur.
    La balise @login_required permet de n'afficher
    cette page que si l'utilisateur est connecté.
    """
    if request.method == "POST":
        substitute = get_object_or_404(Substitute, pk=substitute_pk)
        user = request.user
        substitute.delete()
        return redirect("substitutes")
    else:
        return redirect("frontpage")

def rate_product(request, product_pk):
    if request.method == "POST":
        form = RatingForm(request.POST)
        if form.is_valid():
            note = form.cleaned_data.get('rating')

        product = get_object_or_404(Product, pk=product_pk)
        user = request.user
        rating = Rating.objects.create(product=product, user=user, note=note)

        values = Rating.objects.filter(product=product).values('note')
        users = Rating.objects.filter(product=product).values('user_id')
        try:
            exists = Rating.objects.get(product=product, user=user)
            hasVoted = True
        except Rating.DoesNotExist:
            hasVoted = False

        if values:
            final_note = 0
            count = 0
            for value in values:
                final_note += value["note"]
                count += 1
            _rating = final_note / count
        return render(request, "research/product.html", {"product":product, "rating":_rating, "hasVoted":hasVoted, "form":form})


from src.scripts.financial_statement_converter import FinancialStatementConverter
from src.dao.file_storage_dao import FileStorageDAO
from src.business_objects.company_report import CompanyReport
from src.business_objects.income_statement import IncomeStatement
from src.business_objects.balance_sheet import BalanceSheet
from src.business_objects.cash_flow_statement import CashFlowStatement
from src.business_objects.key_ratios import KeyRatios
from src.business_objects.company_key_metrics_ttm import CompanyKeyMetricsTTM
from src.business_objects.company_quote import CompanyQuote
from scripts.utilities.utils import Utils
import time
import datetime
import json

class ReportGenerator:

    @staticmethod
    def generate_reports(tickers, time_to_live=0):
        for ticker in tickers:
            ReportGenerator.generate_report(ticker, time_to_live)

    @staticmethod
    def generate_report(ticker, time_to_live=0):
        try:
            info = FileStorageDAO.get_company_report(ticker)
            if time.time() - float(info.get('last_updated_date', 0)) < time_to_live:
                return
        except (FileNotFoundError, json.decoder.JSONDecodeError):
            # continue on
            pass
        except BaseException as e:
            print("Unexpected exception when trying to generate report: " + str(e))
            return

        income_statements = FinancialStatementConverter.convert_income_statement_data(ticker)
        balance_sheets = FinancialStatementConverter.convert_balance_statement_data(ticker)
        cash_flow_statements = FinancialStatementConverter.convert_cash_flow_statement_data(ticker)
        key_ratios = FinancialStatementConverter.convert_key_ratio_data(ticker)
        company_key_metrics_ttm = FinancialStatementConverter.convert_company_key_metrics_ttm_data(ticker)
        company_quote = FinancialStatementConverter.convert_company_quote_data(ticker)

        # Part 1 - Growth rates
        equity_growth = ReportGenerator.get_growth_list(balance_sheets, BalanceSheet.SHAREHOLDERS_EQUITY)
        revenue_growth = ReportGenerator.get_growth_list(income_statements, IncomeStatement.REVENUE)
        earnings_growth = ReportGenerator.get_growth_list(income_statements, IncomeStatement.NET_INCOME)
        operating_cash_growth = ReportGenerator.get_growth_list(cash_flow_statements, CashFlowStatement.OPERATING_CASH_FLOW)

        try:
            relevant_growth_rates = [equity_growth[2], equity_growth[9],
                                     revenue_growth[2], revenue_growth[9],
                                     earnings_growth[2], earnings_growth[9],
                                     operating_cash_growth[2], operating_cash_growth[9]]

            # filter out any None values
            lowest_growth_rate = min(rate for rate in relevant_growth_rates if rate is not None)
            conservative_growth_rate = min(.15, lowest_growth_rate)
        except:
            lowest_growth_rate = 0
            conservative_growth_rate = 0

        # Part 2 - P/E and EPS
        pe_ratios = ReportGenerator.get_list(key_ratios, KeyRatios.PE_RATIO)

        positive_pe_ratios = Utils.remove_negative_numbers(pe_ratios)

        estimated_future_pe = max(min(lowest_growth_rate * 2 * 100, Utils.average(positive_pe_ratios)), 0)
        conservative_future_pe = 15

        if len(income_statements) > 0:
            eps = income_statements[0].get(IncomeStatement.EPS)
            eps_diluted = income_statements[0].get(IncomeStatement.EPS_DILUTED)
        else:
            eps = 0
            eps_diluted = 0

        if company_key_metrics_ttm is None:
            eps_ttm = 0
        else:
            eps_ttm = company_key_metrics_ttm.get(CompanyKeyMetricsTTM.EPS)

        if company_quote is None:
            shares_outstanding = 0
        else:
            shares_outstanding = company_quote.get(CompanyQuote.SHARES_OUTSTANDING)

        # Part 3 - Intrinsic value calculation
        intrinsic_value = Utils.calculate_intrinsic_value(eps, lowest_growth_rate, estimated_future_pe)
        conservative_intrinsic_value = Utils.calculate_intrinsic_value(eps_diluted, conservative_growth_rate, conservative_future_pe)

        intrinsic_value_ttm = Utils.calculate_intrinsic_value(eps_ttm, lowest_growth_rate, estimated_future_pe)
        conservative_intrinsic_value_ttm = Utils.calculate_intrinsic_value(eps_ttm, conservative_growth_rate, conservative_future_pe)

        # Part 4 - Create and populate the company report
        company_report = CompanyReport()
        company_report.set_attr(CompanyReport.DATES, ReportGenerator.get_list(income_statements, IncomeStatement.DATE))

        # Set growth rates
        company_report.set_attr(CompanyReport.EQUITY_GROWTH, equity_growth)
        company_report.set_attr(CompanyReport.REVENUE_GROWTH, revenue_growth)
        company_report.set_attr(CompanyReport.EARNINGS_GROWTH, earnings_growth)
        company_report.set_attr(CompanyReport.OPERATING_CASH_GROWTH, operating_cash_growth)

        # Debt, Revenue, Earnings, Equity, ROIC, Return on Equity, Debt to Earnings, Shares Outstanding
        company_report.set_attr(CompanyReport.RETURN_ON_INVESTED_CAPITAL, ReportGenerator.get_list(key_ratios, KeyRatios.ROIC))
        company_report.set_attr(CompanyReport.RETURN_ON_EQUITY, ReportGenerator.get_list(key_ratios, KeyRatios.ROE))
        company_report.set_attr(CompanyReport.TOTAL_DEBT, ReportGenerator.get_list(balance_sheets, BalanceSheet.TOTAL_DEBT))
        company_report.set_attr(CompanyReport.REVENUE, ReportGenerator.get_list(income_statements, IncomeStatement.REVENUE))
        company_report.set_attr(CompanyReport.EARNINGS, ReportGenerator.get_list(income_statements, IncomeStatement.NET_INCOME))
        company_report.set_attr(CompanyReport.EPS_TTM, eps_ttm)
        company_report.set_attr(CompanyReport.EQUITY, ReportGenerator.get_list(balance_sheets, BalanceSheet.SHAREHOLDERS_EQUITY))

        # other
        company_report.set_attr(CompanyReport.TICKER, ticker)
        company_report.set_attr(CompanyReport.NUM_INCOME_STATEMENTS, len(income_statements))
        company_report.set_attr(CompanyReport.NUM_BALANCE_SHEETS, len(balance_sheets))
        company_report.set_attr(CompanyReport.NUM_CASH_FLOW_STATEMENTS, len(cash_flow_statements))

        company_report.set_attr(CompanyReport.EPS, eps)
        company_report.set_attr(CompanyReport.EPS_DILUTED, eps_diluted)
        company_report.set_attr(CompanyReport.PE_RATIOS, pe_ratios)
        company_report.set_attr(CompanyReport.AVERAGE_PE_RATIO, estimated_future_pe)
        company_report.set_attr(CompanyReport.SHARES_OUTSTANDING, shares_outstanding)
        company_report.set_attr(CompanyReport.DEBT_TO_EARNINGS, ReportGenerator.get_list(key_ratios, KeyRatios.DEBT_TO_EARNINGS))

        company_report.set_attr(CompanyReport.INTRINSIC_VALUE, intrinsic_value)
        company_report.set_attr(CompanyReport.INTRINSIC_VALUE_GROWTH_RATE, lowest_growth_rate)
        company_report.set_attr(CompanyReport.CONSERVATIVE_INTRINSIC_VALUE, conservative_intrinsic_value)
        company_report.set_attr(CompanyReport.CONSERVATIVE_INTRINSIC_VALUE_GROWTH_RATE, conservative_growth_rate)

        company_report.set_attr(CompanyReport.INTRINSIC_VALUE_USING_TTM_EPS, intrinsic_value_ttm)
        company_report.set_attr(CompanyReport.CONSERVATIVE_INTRINSIC_VALUE_USING_TTM_EPS, conservative_intrinsic_value_ttm)

        FileStorageDAO.save_report(company_report)

        # Part 5 - create and save the json version of the company report
        company_report_json = {
            CompanyReport.DATES: ReportGenerator.get_list(income_statements, IncomeStatement.DATE),
            CompanyReport.EQUITY_GROWTH: equity_growth,
            CompanyReport.REVENUE_GROWTH: revenue_growth,
            CompanyReport.EARNINGS_GROWTH: earnings_growth,
            CompanyReport.OPERATING_CASH_GROWTH: operating_cash_growth,
            CompanyReport.RETURN_ON_INVESTED_CAPITAL: ReportGenerator.get_list(key_ratios, KeyRatios.ROIC),
            CompanyReport.RETURN_ON_EQUITY: ReportGenerator.get_list(key_ratios, KeyRatios.ROE),
            CompanyReport.TOTAL_DEBT: ReportGenerator.get_list(balance_sheets, BalanceSheet.TOTAL_DEBT),
            CompanyReport.REVENUE: ReportGenerator.get_list(income_statements, IncomeStatement.REVENUE),
            CompanyReport.EARNINGS: ReportGenerator.get_list(income_statements, IncomeStatement.NET_INCOME),
            CompanyReport.EPS_TTM: eps_ttm,
            CompanyReport.EQUITY: ReportGenerator.get_list(balance_sheets, BalanceSheet.SHAREHOLDERS_EQUITY),
            CompanyReport.TICKER: ticker,
            CompanyReport.NUM_INCOME_STATEMENTS: len(income_statements),
            CompanyReport.NUM_BALANCE_SHEETS: len(balance_sheets),
            CompanyReport.NUM_CASH_FLOW_STATEMENTS: len(cash_flow_statements),
            CompanyReport.EPS: eps,
            CompanyReport.EPS_DILUTED: eps_diluted,
            CompanyReport.PE_RATIOS: pe_ratios,
            CompanyReport.AVERAGE_PE_RATIO: estimated_future_pe,
            CompanyReport.SHARES_OUTSTANDING: shares_outstanding,
            CompanyReport.DEBT_TO_EARNINGS: ReportGenerator.get_list(key_ratios, KeyRatios.DEBT_TO_EARNINGS),
            CompanyReport.INTRINSIC_VALUE: intrinsic_value,
            CompanyReport.INTRINSIC_VALUE_GROWTH_RATE: lowest_growth_rate,
            CompanyReport.CONSERVATIVE_INTRINSIC_VALUE: conservative_intrinsic_value,
            CompanyReport.CONSERVATIVE_INTRINSIC_VALUE_GROWTH_RATE: conservative_growth_rate,
            CompanyReport.INTRINSIC_VALUE_USING_TTM_EPS: intrinsic_value_ttm,
            CompanyReport.CONSERVATIVE_INTRINSIC_VALUE_USING_TTM_EPS: conservative_intrinsic_value_ttm,
            'last_updated_date': time.time(),
            'last_updated_date_human': str(datetime.datetime.now())
        }

        FileStorageDAO.save_company_report_json(ticker, company_report_json)

    @staticmethod
    def get_growth(statements, num_years, attr):
        if len(statements) < num_years or len(statements) == 0:
            return 'no data'
        try:
            starting_value = float(statements[num_years].get(attr))
            ending_value = float(statements[0].get(attr))
            return Utils.calculate_yoy_return(starting_value, ending_value, num_years)
        except:
            return 'error'

    @staticmethod
    def get_value(statements, num_years, attr):
        if len(statements) < num_years:
            return 'no data'
        return float(statements[num_years].get(attr))

    @staticmethod
    def get_list(statements, attr):
        """
        :param statements: a list of financial statements
        :param attr: the attribute you want
        :return: a list containing all the values of that particular attribute
        """
        ret = []
        for i in range(len(statements)):
            ret.append(statements[i].get(attr))
        return ret

    @staticmethod
    def get_growth_list(statements, attr):
        ret = []

        # start from 1 since growth requires more than 0 years
        for i in range(1, len(statements)):
            ret.append(ReportGenerator.get_growth(statements, i, attr))
        return ret

# print(Utils.calculate_payback_time(3185, 501000000, .25, 17377000000))
# FileStorageDAO._make_directories()
# ReportGenerator.generate_report('F')
# print(Utils.calculate_intrinsic_value(34.8,.25,50))


import tensorflow as tf
import numpy as np
import shfl

from sklearn.metrics import classification_report

class ClassifierModel(shfl.model.DeepLearningModel):

    def __init__(self, dict_labels, batch_size, epochs, finetune):

        #dict labels: letra -> bin
        self._dict_labels = dict_labels

        if finetune:
            resnet50 = tf.keras.applications.ResNet50(include_top = False, weights = 'imagenet', pooling = 'avg', input_tensor=tf.keras.layers.Input(shape=(224, 224, 3)))
        else:
            resnet50 = tf.keras.applications.ResNet50(include_top = False, weights = None, pooling = 'avg', input_tensor=tf.keras.layers.Input(shape=(224, 224, 3)))

        # Add last layers
        x = resnet50.output
        x = tf.keras.layers.Dense(512, activation = 'relu')(x)
        predictions = tf.keras.layers.Dense(4, activation = 'softmax')(x)

        self._model = tf.keras.Model(inputs = resnet50.input, outputs = predictions)
        self._data_shape = self._model.layers[0].get_input_shape_at(0)[1:]
        self._labels_shape = self._model.layers[-1].get_output_shape_at(0)[1:]

        self._criterion = tf.keras.losses.CategoricalCrossentropy()
        self._optimizer = tf.keras.optimizers.SGD(lr = 1e-3, decay = 1e-6, momentum = 0.9, nesterov = True)
        self._metrics = [tf.keras.metrics.categorical_accuracy]
        #self._metrics = [tf.keras.metrics.Accuracy()]

        self._batch_size = batch_size
        self._epochs = epochs

        self._model.compile(optimizer=self._optimizer, loss=self._criterion, metrics=self._metrics)

    def train(self, data, labels):

        train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(
                                            preprocessing_function = tf.keras.applications.resnet50.preprocess_input,
                                            #rotation_range = 5,
                                            #width_shift_range = 0.5,
                                            #height_shift_range = 0.5,
                                            #horizontal_flip = True,
                                            validation_split=0.1
                                          )
        train_generator = train_datagen.flow(data, labels, batch_size=self._batch_size, subset='training', shuffle=True)
        validation_generator = train_datagen.flow(data, labels, batch_size=1, subset='validation', shuffle=False)

        #early_stopping = tf.keras.callbacks.EarlyStopping(monitor = 'val_loss', patience = 10, verbose=1, restore_best_weights = True)
        early_stopping = tf.keras.callbacks.EarlyStopping(monitor = 'val_categorical_accuracy', patience = 10, verbose=1, restore_best_weights = True)
        self._model.fit(
            x=train_generator,
            steps_per_epoch= int(len(data)*0.9) // self._batch_size,
            validation_data = validation_generator,
            validation_steps = int(len(data)*0.1),
            epochs=self._epochs,
            callbacks = [early_stopping]
        )

    def predict(self, data):

        #probs = self._model.predict(data, batch_size=self._batch_size)

        preds = []
        preds_4 = []
        no_concuerda = 0
        for i in range(int(len(data)/2)):

            tn = data[2*i]
            tp = data[2*i+1]

            tn = np.expand_dims(tn, axis = 0)
            tp = np.expand_dims(tp, axis = 0)
            tp = tf.keras.applications.resnet50.preprocess_input(tp)
            tn = tf.keras.applications.resnet50.preprocess_input(tn)

            prob_tn = self._model.predict(tn)[0]
            prob_tp = self._model.predict(tp)[0]

            pred_tp = np.argmax(prob_tp)
            pred_tn = np.argmax(prob_tn)

            preds_4.append(pred_tn)
            preds_4.append(pred_tp)

            if pred_tp == self._dict_labels['NTP'] and pred_tn == self._dict_labels['NTN']:
                pred = self._dict_labels['N']
            elif pred_tp == self._dict_labels['PTP'] and pred_tn == self._dict_labels['PTN']:
                pred = self._dict_labels['P']
            else:
                no_concuerda = no_concuerda + 1
                # prob_p = prob_tp[0][dict['PTP']] + prob_tp[0][dict['PTN']] + prob_tn[0][dict['PTP']] + prob_tn[0][dict['PTN']]
                # prob_n = prob_tp[0][dict['NTP']] + prob_tp[0][dict['NTN']] + prob_tn[0][dict['NTP']] + prob_tn[0][dict['NTN']]
                prob_p = max(prob_tp[self._dict_labels['PTP']], prob_tp[self._dict_labels['PTN']], prob_tn[self._dict_labels['PTP']], prob_tn[self._dict_labels['PTN']])
                prob_n = max(prob_tp[self._dict_labels['NTP']], prob_tp[self._dict_labels['NTN']], prob_tn[self._dict_labels['NTP']], prob_tn[self._dict_labels['NTN']])
                if prob_p >= prob_n:
                    pred = self._dict_labels['P']
                else:
                    pred = self._dict_labels['N']

            preds.append(pred)

        preds = np.array(preds)
        preds_4 = np.array(preds_4)

        return preds, preds_4, no_concuerda

    def evaluate(self, data, labels):
        preds, preds_4, no_concuerda, = self.predict(data)

        labels_4 = np.array([np.argmax(l) for l in labels])
        labels_2 = []

        for i in range(int(len(labels)/2)):
            lab = np.argmax(labels[2*i])
            if lab == self._dict_labels['PTP'] or lab == self._dict_labels['PTN']:
                etiq = 'P'
            else:
                etiq = 'N'

            labels_2.append(self._dict_labels[etiq])

        labels_2 = np.array(labels_2)

        acc_4 = sum(labels_4 == preds_4)/len(labels_4)

        acc = sum(labels_2 == preds)/len(labels_2)

        cr = classification_report(labels_2, preds, digits = 5, output_dict = True)

        metrics = [acc, acc_4, no_concuerda, cr]

        return metrics

    def save(self, path):
        self._model.save(path + "SDNET_C.h5")

    def load(self, path):
        self._model = tf.keras.models.load_model(path + "SDNET_C.h5")


"""Routes configuration

The more specific and detailed routes should be defined first so they
may take precedent over the more generic routes. For more information
refer to the routes manual at http://routes.groovie.org/docs/
"""
from pylons import config
from routes import Mapper

def make_map():
    """Create, configure and return the routes Mapper"""
    map = Mapper(directory=config['pylons.paths']['controllers'],
        always_scan=config['debug'])
    map.minimization = False

    # The ErrorController route (handles 404/500 error pages); it should
    # likely stay at the top, ensuring it can always be resolved
    map.connect('/error/{action}', controller='error')
    map.connect('/error/{action}/{id}', controller='error')

    # CUSTOM ROUTES HERE
    map.connect('/signout', controller='account', action='signin')
    map.connect('/signin', controller='account', action='signin')
    map.connect('/', controller='marketing', action='homepage')
    map.connect('/handler/{controller}', action='handler')
    map.connect('/dashboard', controller='dashboard', action='index')
    map.connect('/users', controller='user', action='index')
    map.connect('/users/{propertyId}', controller='user', action='index')
    map.connect('/property', controller='property', action='index')
    map.connect('/reports', controller='reports', action='transactions')
    map.connect('/contacts', controller='contacts', action='index')
    map.connect('/contacts/json/{type}', controller='contacts', action='json')
    map.connect('/activate/{id}', controller='account', action='activate')
    map.connect('/newPassword/{id}', controller='account', action='newPassword')
    map.connect('/account', controller='account', action='manage')
    map.connect('/company', controller='company', action='manage')
    map.connect('/search', controller='search', action='index')
    map.connect('/help', controller='help', action='index')
    map.connect('/autocomplete', controller='search', action='autocomplete')
    map.connect('/{controller}/{action}')
    map.connect('/{controller}/{action}/{id}')
    map.connect('/{controller}/{action}/{id}/{unitId}', controller='property', action='setup')

    return map


import arcade
SCREEN_WIDTH=800
SCREEN_HEIGHT=600
def suelo():
    """Dibuja el suelo"""
    arcade.draw_lrtb_rectangle_filled(0, SCREEN_WIDTH, SCREEN_HEIGHT / 3, 0, arcade.color.AIR_SUPERIORITY_BLUE)
def cabeza(x,y):
    """Dibuja la cabeza"""
    arcade.draw_circle_filled(300+x, 200+y, 10, arcade.color.YELLOW)
    arcade.draw_circle_filled(296+x, 205+y, 3, arcade.color.BLACK)
    arcade.draw_circle_filled(304+x, 205+y, 3, arcade.color.BLACK)
def on_draw(delta_time):
    arcade.start_render()
    suelo()
    cabeza(on_draw.coordenada_x, on_draw.coordenada_y)
    cabeza(-20, -20)
    on_draw.coordenada_x +=1
    on_draw.coordenada_y +=2
on_draw.coordenada_x=0
on_draw.coordenada_y=0
def main():
    arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Drawing with Functions")
    arcade.set_background_color(arcade.color.DARK_BLUE)

    arcade.schedule(on_draw,1/60)
    arcade.run()

main()


import sys

import bdatos
import configparser
import os
import errno
import time
from ping3 import ping as pineador

# ---------------------VARIABLES----------------------------
ANCHO = 2
LARGO = 2
RUTA = "dataConfig"
ARCHIVO = RUTA + "/configuracion.ini"

# ----------------------------------------------------------

# ---------------BASE DE DATOS-----------------
def obtener_servidores():
    resultado = ()
    for servidor in bdatos.cargar_servidores():
        resultado = resultado + servidor
    return resultado

# ----------------------------------------------------------

# ---------------CONFIGURACION------------------------------
def existe_configuracion(objeto=None):
    if not os.path.exists(ARCHIVO):
        crear_configuracion()
        bdatos.existe_bd()
    elif objeto == None:
        guardar_configuracion_ini("servidor_actual", "localhost")
    if objeto != None:
        objeto.read(ARCHIVO)

def crear_configuracion():
    try:
        os.mkdir(RUTA)
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise
    configuracion = configparser.ConfigParser()
    try:
        configuracion.add_section("CONFIGURACION")
    except configparser.DuplicateSectionError:
        pass
    configuracion.set("CONFIGURACION", "servidor_actual", "localhost")
    configuracion.set("CONFIGURACION", "regular_ping", "300")
    configuracion.set("CONFIGURACION", "mal_ping", "1000")
    configuracion.set("CONFIGURACION", "cantidad_pings", "60")
    with open(ARCHIVO, "w") as archivo_de_configuracion:
        configuracion.write(archivo_de_configuracion)

def guardar_configuracion_ini(key, valor):
    configuracion = configparser.ConfigParser()
    existe_configuracion(objeto=configuracion)
    try:
        configuracion.set("CONFIGURACION", key, valor)
        with open(ARCHIVO, "w") as archivo_de_configuracion:
            configuracion.write(archivo_de_configuracion)
    except:
        crear_configuracion()

def crear_obcion(key):
    configuracion = configparser.ConfigParser()
    existe_configuracion(objeto=configuracion)
    try:
        configuracion.set("CONFIGURACION", key, "")
        with open(ARCHIVO, "w") as archivo_de_configuracion:
            configuracion.write(archivo_de_configuracion)
    except configparser.NoSectionError:
        crear_configuracion()

def leer_configuracion(key):
    configuracion = configparser.ConfigParser()
    existe_configuracion(objeto=configuracion)
    try:
        value = configuracion.get("CONFIGURACION", key)
        return value
    except configparser.NoSectionError:
        crear_configuracion()
        return leer_configuracion(key)
    except configparser.NoOptionError:
        crear_obcion(key)
        return leer_configuracion(key)

def servidor_actual():
    return leer_configuracion("servidor_actual")

def regular_ping():
    return leer_configuracion("regular_ping")

def mal_ping():
    return leer_configuracion("mal_ping")

def cantidad_pings():
    return leer_configuracion("cantidad_pings")

# ----------------------------------------------------------

def cerrar_aplicacion(aplicacion):
    aplicacion.hilo = False
    aplicacion.destroy()

def redondear_o_Nulear(dato):
    if dato == None:
        return "---"
    else:
        return round(dato)

def reiniciar_pings(raiz, e):
    raiz.L_maximoping["text"] = "MAX: ---"
    raiz.L_minimoping["text"] = "MIN: ---"
    raiz.L_promedioping["text"] = "PROM: ---"
    raiz.L_perdidaping["text"] = "LOST: ---"
    raiz.F_cobertura.configure(style="Red.TFrame")
    raiz.nueva_direccion = True

def resource_path(relative_path):
    """ Get absolute path to resource, works for dev and for PyInstaller """
    try:
        # PyInstaller creates a temp folder and stores path in _MEIPASS
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")

    return os.path.join(base_path, relative_path)

def pinear2(raiz, id):
    if raiz.tv_servidores.condicional:
        raiz.tv_servidores.set(id, 'MAX', str(maximo_ping(raiz.tv_servidores.hilos[id]["pings"])) + "ms")
        raiz.tv_servidores.set(id, 'MIN', str(minimo_ping(raiz.tv_servidores.hilos[id]["pings"])) + "ms")
        raiz.tv_servidores.set(id, 'PROM', str(promedio_ping(raiz.tv_servidores.hilos[id]["pings"])) + "ms")
        raiz.tv_servidores.set(id, 'LOST', str(perdida_ping(raiz.tv_servidores.hilos[id]["pings"])) + "%")

def calcular_ping2(raiz, id, nombre):
    while raiz.tv_servidores.condicional:
        direccion = bdatos.obtener_direccion(nombre)
        tiempo_de_espera = ping_en_profundidad(raiz.tv_servidores.hilos[id]["pings"], direccion)
        pinear2(raiz, id)
        eliminar_pings_vencidos(raiz.tv_servidores.hilos[id]["pings"])
        esperar(tiempo_de_espera)

def maximo_ping(list):
    MAX = None
    for pin in list:
        if pin != None:
            if MAX == None or MAX < pin:
                MAX = pin
    return redondear_o_Nulear(MAX)

def minimo_ping(list):
    MIN = None
    for pin in list:
        if pin != None:
            if MIN == None or MIN > pin:
                MIN = pin
    return redondear_o_Nulear(MIN)

def promedio_ping(list):
    suma_total = None
    conteo = 0
    for pin in list:
        if pin != None:
            if suma_total == None:
                suma_total = pin
            else:
                suma_total += pin
            conteo += 1
    if suma_total == None:
        return redondear_o_Nulear(None)
    else:
        return redondear_o_Nulear(suma_total / conteo)

def perdida_ping(list):
    suma_total = 0
    if len(list) != 0:
        for pin in list:
            if pin == None:
                suma_total += 1
        return redondear_o_Nulear(suma_total / len(list) * 100)
    return "---"

def ping_en_profundidad(list, direccion):
    inicio = time.time()
    try:
        ping = pineador(direccion, timeout=1)
    except:
        ping = False
    if type(ping) in (float, int):
        ping = ping * 1000
        lantencia = round(ping) / 1000
        tiempo_de_espera = 1 - lantencia
        list.append(ping)
    else:
        list.append(None)
        final = time.time()
        tiempo_de_espera = (1000 - (final - inicio)) / 1000
    return tiempo_de_espera

def eliminar_pings_vencidos(list):
    if len(list) > int(leer_configuracion("cantidad_pings")):
        list.pop(0)

def esperar(tiempo_de_espera):
    if tiempo_de_espera > 0:
        time.sleep(tiempo_de_espera)


import urllib.request
import threading
import time

class ScrapeTwoInchBrush(object):

    base_url = "https://www.twoinchbrush.com/images/painting"
    file_path = "raw_data/"
    pool_size = 32
    amount_of_images = 0
    total_time = 0

    def saveImage(self, url, file_num):
        file_path = self.file_path + "{}.png".format(str(file_num).zfill(3))
        urllib.request.urlretrieve(url, file_path)
        self.amount_of_images += 1

    def getImages(self, image_num):
        url = self.base_url + "{}.png".format(image_num)
        try:
            self.saveImage(url, image_num)
        except urllib.error.HTTPError:
            print("Failed to get {}".format(image_num))

    def scrape(self, search_range=(0, 500)):
        threads = [threading.Thread(target=self.getImages, args=(
            image_num,)) for image_num in range(*search_range)]
        for thread in threads:
            thread.start()
        for thread in threads:
            thread.join()

    def pool(self, search_range):
        old = search_range[0]
        start = time.time()
        for search_range in range(0, search_range[1], self.pool_size):
            self.scrape((old, search_range + self.pool_size))
            old = search_range + self.pool_size
        self.total_time += time.time() - start

scraper = ScrapeTwoInchBrush()
scraper.pool((0, 412))
print(scraper.total_time)
print(scraper.amount_of_images)