import os
import dash_bootstrap_components as dbc
from dash import Input, Output, State, html
import dash
import base64
from controller import Controller
from datetime import date
import predict
from dash import dcc, html
import warnings
import time
import pandas as pd
import numpy as np
from dash import Dash, dash_table

warnings.filterwarnings("ignore")
## Diskcache
import flask

from waitress import serve

_start_time = time.time()

server = flask.Flask(__name__)

app = dash.Dash(
    server=server,
    external_stylesheets=[dbc.themes.BOOTSTRAP, dbc.icons.BOOTSTRAP],
    # serve_locally=False,
)

# url_bar_and_content_div = html.Div([
#     dcc.Location(id='url', refresh=False),
#     html.Div(id='page-content')
# ])

EXPERIS_LOGO = "http://health5g.eu/wp-content/uploads/2019/09/Experis-IT.png"
ctrl = Controller()
navbar = dbc.Navbar(
    dbc.Container(
        [
            html.A(
                dbc.Row(
                    [
                        dbc.Col(html.Img(src=EXPERIS_LOGO, height="60px"), style={"margin-right": "5px"}),
                        dbc.Col(dbc.NavbarBrand("Recommendation Engine", className="ms-2",
                                                style={"color": "#4C5154", "font-size": "30px"}),
                                style={"margin-left": "5px"}),
                    ],
                    align="center",
                    className="g-0",
                ),
                style={"textDecoration": "none"},
            ),
            dbc.NavbarToggler(id="navbar-toggler", n_clicks=0),
            dbc.Collapse(
                id="navbar-collapse",
                is_open=False,
                navbar=True,
            ),
        ]
    ),
    color="light",
    dark=True,
)

uploader = dbc.Row(

    dbc.Col([

        dcc.Upload(
            id="upload-resume",
            children=html.Div(
                ["Trascina e rilascia o clicca per caricare un curriculum",

                 ],       id="upload", n_clicks=0,

            ),
            style={
                "width": "50%",
                "height": "60px",
                "line-height": "60px",
                "border-width": "1px",
                "border-style": "line",
                "border-radius": "10px",
                "text-align": "center",

                "background-color": "#0D6EFD",
                "color": "white",
                "margin-left": "25%",
                "margin-right": "25%",
                "margin-top": "10px",
                "margin-bottom": "10px"

            },
            multiple=True, disabled =False
        ),

        html.Div(id='output-upload'),
        html.Br(),

        dcc.Loading(id="loading-resume", children=[html.Div(id="output-resume")], type="default"),
        dbc.RadioItems(id='radio_items'),

    ],
        width={"size": 10, "offset": 1}),

)
jobs_recommended = dcc.Loading(id="loading-recommendations",
                               children=[html.Div(id="recommendations"),html.Div(id="refresh")], type="default")

# layout_page_1 = html.Div([
#     dbc.Card(
#         [
#
#             dbc.CardBody(
#
#                 dbc.Row(
#                     [
#                         dbc.Col(
#                             html.H1(
#                                 html.B("Servizio non disponibile"),
#                                 className="text-center mt-4 mb-5",
#                                 style={"color": "Purple", "text-decoration": "None", },
#                             )
#                         )
#                     ]
#                 ),
#             ),
#         ],
#
#         style={"height": "100%"},
#     )
# ])

layout_page_2 = html.Div([
    uploader, html.Br(), jobs_recommended,

])

app.layout = html.Div([

    # dcc.Location(id='url', refresh=False),
    # html.Div(id='page-content')

dbc.Navbar(
            dbc.Container(
                [
                    html.A(
                        dbc.Row(
                            [

                                dbc.Col(html.Img(src=EXPERIS_LOGO, height="60px"), style={"margin-right": "5px"}),
                                dbc.Col(dbc.NavbarBrand("Recommendation Engine", className="ms-2",
                                                        style={"color": "#4C5154", "font-size": "30px"}),width=8
                                        ),
                                # dbc.Col(html.A(html.Button('Refresh Page',
                                #                            style={'margin-bottom': '10px',
                                #                                   "fontSize": "1em",
                                #                                   "background-color": "white", "color": "black",
                                #                                   "border-radius": "10px",
                                #                                   "border": "2px solid dodgerblue"}),
                                #                href=relative_pathname),align="end",
                                #         ),

                            ],
                            align="center",
                            className="g-0",
                        ),
                        style={"textDecoration": "none"},
                    ),
                    dbc.NavbarToggler(id="navbar-toggler", n_clicks=0),
                    dbc.Collapse(
                        id="navbar-collapse",
                        is_open=False,
                        navbar=True,
                    ),
                ]
            ),
            color="light",
            dark=True,
        ),
        layout_page_2,

])

# @app.callback(Output('page-content', 'children'),
#               Input('url', 'pathname'))
# def display_page(relative_pathname):
#     return html.Div([
#
#         dbc.Navbar(
#             dbc.Container(
#                 [
#                     html.A(
#                         dbc.Row(
#                             [
#
#
#                                 dbc.Col(html.Img(src=EXPERIS_LOGO, height="60px"), style={"margin-right": "5px"}),
#                                 dbc.Col(dbc.NavbarBrand("Recommendation Engine", className="ms-2",
#                                                         style={"color": "#4C5154", "font-size": "30px"}),width=8
#                                         ),
#                                 # dbc.Col(html.A(html.Button('Refresh Page',
#                                 #                            style={'margin-bottom': '10px',
#                                 #                                   "fontSize": "1em",
#                                 #                                   "background-color": "white", "color": "black",
#                                 #                                   "border-radius": "10px",
#                                 #                                   "border": "2px solid dodgerblue"}),
#                                 #                href=relative_pathname),align="end",
#                                 #         ),
#
#
#                             ],
#                             align="center",
#                             className="g-0",
#                         ),
#                         style={"textDecoration": "none"},
#                     ),
#                     dbc.NavbarToggler(id="navbar-toggler", n_clicks=0),
#                     dbc.Collapse(
#                         id="navbar-collapse",
#                         is_open=False,
#                         navbar=True,
#                     ),
#                 ]
#             ),
#             color="light",
#             dark=True,
#         ),
#         layout_page_2,
#
#
#     ])

@app.callback(
            Output('output-upload', 'children'),
            Output("upload-resume", "disabled"),
            Output("upload-resume", "style"),
    inputs= [Input('upload-resume', 'contents'),
            State('upload-resume', 'filename')]
)
def select_pdf(list_of_contents, list_of_names):
    if list_of_contents is not None:
        content_type, content_string = list_of_contents[0].split(',')
        # ctrl.set_filename (list_of_names)

        dizlist = {}
        for contents, filename in zip(list_of_contents, list_of_names):
            content_type, content_string = contents.split(',')

            dizlist[filename] = contents

            if 'pdf' in content_type:
                decoded_resume = base64.b64decode(content_string)
                global name

                resume_uploaded = os.path.join(os.getcwd(), filename)

            with open(resume_uploaded, "wb") as resume:
                resume.write(decoded_resume)
        ctrl.set_contents(dizlist)
        children = dbc.Card([

            dbc.Modal(
                [
                    dbc.ModalHeader(dbc.ModalTitle("Attenzione"), style={"color": "white", "background-color": "#f0833c"}),
                    dbc.ModalBody("Non hai selezionato la cartella per il salvataggio dei risultati!"),
                    dbc.ModalFooter(
                        dbc.Button(
                            "Close", id="close1", className="ms-auto", n_clicks=0
                        )
                    ),
                ],
                id="modal",
                is_open=False,
            ),

            dbc.Row(
                [
                    dbc.Col(

                        dbc.Card(
                            [
                                dbc.CardHeader("Curriculum da processare", style={"color":"white", "background-color": "#f0833c", "font-weight": "bold"}),
                                dbc.CardBody([
                                    html.Div([

                                        dbc.RadioItems(id='radio_items', options=[{
                                            'label': v,
                                            'value': v
                                        } for v in list_of_names], value=list_of_names[0], inline=True
                                                       , style={"margin-right": "20px", "font-weight": "bold", "font-size":"20px", "color": "dimgray"}),
                                        html.Br(),
                                    ]),

                                ]
                                )

                            ], color="light", style={"width": "100%","height":"100%"}),

                        width={"size": 6},

                    ),
                    # dbc.Col( align="center",  width={"size": 2},),
                    dbc.Col(

                        dbc.Card(
                            [
                                dbc.CardHeader("Salvataggio dei risultati",  style={"color":"white", "background-color": "#779788", "font-weight": "bold"}),
                                dbc.CardBody([
                                    html.Div([
                                        html.Div([
                                            dbc.Button('Salva i risultati in ...', id="open_directory",
                                                       n_clicks=0,
                                                       style={"text-align": "center"}, disabled=False,

                                                       # color="link",
                                                       ),
                                        ], className="d-grid gap-2"),

                                        html.Div(id='selected_directory', children='No directory selected!', style={"margin-top":"5px", "margin-bottom":"2px", "text-align": "center"}),
                                        html.Div(id="out-all-types"),
                                    ]),

                                ]
                                )

                            ], color="light", style={"width": "100%","height":"100%"}),
                        width={"size": 6},

                    ),

                ],

            ),

            html.Hr(style={"border-top": "1px dashed gray"}),

            dbc.Row(
                [
                    dbc.Col(
                        children=[
                            html.Div(
                                html.Div(
                                    dbc.Button(html.Span([html.I(className="bi bi-search me-2"), "Analizza"]),
                                               color="primary", style={"text-align": "center", "font-weight": "bold",
                                                                       "font-size": "25px"},
                                               id="recommendationbtn", disabled=False,
                                               n_clicks=0),

                                    style={"text-align": "center", "margin-bottom": "10px"},
                                    id="recommendation-btn", n_clicks=0, className="d-grid gap-2")
                            ),

                            html.A(

                            html.Div(
                                html.Div(

                                    dbc.Button(html.Span([html.I(className="bi bi-arrow-clockwise me-2"), "Nuove analisi"]),
                                               color="danger", style={"text-align": "center", "font-weight": "bold",
                                                                       "font-size": "25px"},
                                               id="cleanbtn", disabled=False,
                                               n_clicks=0),

                                    style={"text-align": "center", "margin-bottom": "10px"},
                                    id="clean-btn", n_clicks=0, className="d-grid gap-2")
                            ), href='/', style={"text-decoration": "none"}
                            ),

                        ],

                        width={"size": 4, "offset": 4}),
                    # dbc.Col(html.Div(), md=4),

                ]
            ),

            ],
            style={"width": "100%", "margin-left": "10px", "margin-bottom": "10px", "margin-top": "10px", "padding": "10px"}, color="light")

        return [children, True, {
                "width": "50%",
                "height": "60px",
                "line-height": "60px",
                "border-width": "1px",
                "border-style": "line",
                "border-radius": "10px",
                "text-align": "center",

                "background-color": "#6c757d",
                "color": "white",
                "margin-left": "25%",
                "margin-right": "25%",
                "margin-top": "10px",
                "margin-bottom": "10px"

            }]
    else:
        return [html.Div(), False,  {
                "width": "50%",
                "height": "60px",
                "line-height": "60px",
                "border-width": "1px",
                "border-style": "line",
                "border-radius": "10px",
                "text-align": "center",

                "background-color": "#0D6EFD",
                "color": "white",
                "margin-left": "25%",
                "margin-right": "25%",
                "margin-top": "10px",
                "margin-bottom": "10px"

            },]

#

@app.callback(output=Output('output-resume', 'children'),
              inputs=[
                  Input('radio_items', 'value'), ])
def update_items(value):
    if value is not None:
        ctrl.folder = None
        diz = ctrl.get_contents()
        content_string = diz[value]
        resume_card = dbc.Card([
            dbc.CardHeader(
                html.Div([html.Span(value, style={"font-style": "italic", "color": "#5078b4"}),

                    dbc.Button(
                    "Mostra/Nascondi",
                    id="collapse-button",
                    className="mb-3",
                    color="info",
                    n_clicks=0,
                    style={"color": "white", "font-weight": "bold"}
                ), ], className="d-flex w-100 justify-content-between")

            ),

            dbc.Collapse(

                dbc.CardBody(
                    [

                        html.ObjectEl(data=content_string,
                                      type='application/pdf',
                                      width="100%", height="1000px"
                                      )
                    ]
                ),

                id="resume-collapse",
                is_open=True,
            )

        ],
            style={"width": "100%", "margin-left": "10px"}, color="light")
        return resume_card
    else:
        return html.Div()

@app.callback(
    output=Output("resume-collapse", "is_open"),
    inputs=
    [Input("collapse-button", "n_clicks"), State("resume-collapse", "is_open")],
)
def toggle_collapse(n, is_open):
    if n:
        return not is_open
    return is_open

@app.callback(
    Output("out-all-types", "children"),
    inputs=[
        Input("input1", "value")]
)
def set_namesresults(input1):
    ctrl.set_filenameresult(input1)
    return html.Div()

@app.callback(
    Output(component_id='selected_directory', component_property='children'),
     Output('open_directory','disabled'),
    inputs=[Input(component_id='open_directory', component_property='n_clicks'),
            ]
)
def set_folder(n):
    if n:

        import tkinter
        from tkinter import filedialog

        root = tkinter.Tk()
        # root.withdraw()

        directory = filedialog.askdirectory()

        # root.mainloop()
        root.destroy()

        ctrl.folder = directory

        folder_container = html.Span(directory, style={"font-weight": "bold", "font-size":"20px", "color": "dimgray"}),

        return [folder_container, True]
    else:
        return [html.Div(), False]

@app.callback(
    Output("recommendationbtn", "disabled"),
    inputs=[Input("recommendationbtn", "n_clicks")]
)

def search(n_clicks):
    directory = ctrl.folder
    if n_clicks and directory :
        return True

@app.callback(
    Output("recommendations", "children"), Output("modal", "is_open"),
    inputs=[Input("recommendation-btn", "n_clicks"), Input("close1", "n_clicks"), State("modal", "is_open")],
)
def get_skilss(n, n2, is_open):
    directory = ctrl.folder
    print(directory)
    listanomi=['responsabile','direttore','direttrice','amministratrice','coordinatrice','amministratore','responsabile','account manager','account manage',
               'account executive direct','amministratore','amministratrice','capa','capo',"coordinatrice",'coordinatore','manager',
               'dirigente','funzionaria','funzionario','head','ispettore','ispettrice','leader','padrona','padrone','pianificatore','project lead',
            'contabile','manager' ,'pianificatrice','strategic' ]
    if (n or n2) and directory is None:
        return html.Div(), not is_open

    if n and directory is not None:

        files = list(ctrl.get_contents().keys())

        global skillsner, category
        today = date.today()

        d1 = today.strftime("%d-%m-%Y")
        namer = ctrl.get_filenameresult()

        cards = []
        for pdfnamepath in files:
            name = pdfnamepath.replace("pdf", ' ')
            folder = directory.split('/') + ['skills_' + namer + "_" + name + "_" + str(d1) + '.xlsx']

            folder[0] = folder[0] + '/'

            path = os.path.join(*folder)

            rs = predict.main(pdfnamepath, path)
            rs.sort_values(by=['scoreFinal'], ascending=False, inplace=True)

            # rs['N°'] = pd.Series(np.arange(1, rs.shape[0]+1), index=rs.index)
            rs['Composite Score'] = rs['scoreFinal'].astype('float').round(2).apply(lambda x: int(x*100)).astype('str').map("{}%".format)
            rs['TimeScore'] = rs['scoreTime'].astype('float').round(2).apply(lambda x: int(x*100)).astype('str').map("{}%".format)
            rs['DomainScore'] = rs['scoreDom'].astype('float').round(2).apply(lambda x: int(x*100)).astype('str').map("{}%".format)
            rs['SkillsScore'] = rs['scoreSkills'].astype('float').round(2).apply(lambda x: int(x*100)).astype('str').map("{}%".format)
            rs['Post'] = rs['jobDescription'].apply(lambda x: x[:200]).map("{}...".format)
            # rs['scorCompany'] = rs['scorCompany'].astype('float').round(2).apply(lambda x: int(x * 100)).astype(
            #     'str').map("{}%".format)

            rs.reset_index(inplace=True)

           # print(rs['company user'].values.tolist())

            # (scoreTime*scoreDomain + scoreSkills)/2
            # N°'

            subset_rs = rs[['job user', 'company user', 'namescoe','Composite Score', 'TimeScore',\
                            'DomainScore', 'SkillsScore', "scorCompany",'jobTitle', 'jobCompany', 'Post', 'Apply']]
            subset_rs.rename(columns={'job user': 'Candidate job title', 'jobCompany': 'Company post', 'company user': 'Candidate company', \
                                      'jobTitle': 'Post job title','scorCompany':'CompanyScore','namescoe':'Company type'}, inplace=True)

            os.remove(pdfnamepath)

            card = dbc.Card(
                [

                    dbc.CardBody([
                        dash_table.DataTable(
                            data=
                            subset_rs.to_dict('records'),
                            columns=
                            [{"name": i, "id": i} for i in subset_rs.columns],
                            tooltip_header={i: i for i in subset_rs.columns},
                            tooltip_data=[
                                {
                                    column: {'value': str(value), 'type': 'markdown'}
                                    for column, value in row.items()
                                } for row in subset_rs.to_dict('records')
                            ],
                            css=[{
                                'selector': '.dash-table-tooltip',
                                'rule': 'background-color: grey; font-family: monospace; color: white',

                            }],

                            # ,fill_width=False,
                            style_header={
                                'fontSize': 17,
                                # 'textDecoration': 'underline',
                                'fontWeight': "bold",
                                'backgroundColor': "#5078b4",
                                "color": "white",
                                "fontFamily": "Arial,Helvetica Neue,Helvetica,sans-serif"

                            },

                            # Overflow into ellipsis

                            style_cell={
                                'overflow': 'hidden', 'fontSize': 15,
                                'textOverflow': 'ellipsis', "width": "50%", 'maxWidth': 100,
                                "fontFamily": "Arial,Helvetica Neue,Helvetica,sans-serif"

                            },

                            tooltip_delay=0,
                            tooltip_duration=None,

                            style_data_conditional=[

                                {
                                    'if': {
                                        'column_id': 'Apply',
                                    },
                                    'backgroundColor': '#98FB98',
                                    'color': 'red', 'fontWeight': 'bold'
                                },

                            ],

                            style_cell_conditional = [

                                #{'if': {'column_id': 'N°'},
                                 #'width': '5%'},

                                {'if': {'column_id': 'Candidate company'},
                                 'width': '20%'},
                                {'if': {'column_id': 'Composite Score'},
                                 'width': '15%', 'font-weight': 'bold', "color": "#f0833c"},
                                {'if': {'column_id': 'Company post'},
                                 'width': '20%'},
                                {'if': {'column_id': 'TimeScore'},
                                 'font-weight': 'bold', "color": "#5078b4", "width": "15%"},
                                {'if': {'column_id': 'DomainScore'},
                                 'font-weight': 'bold', "color": "#5078b4"},
                                {'if': {'column_id': 'SkillsScore'},
                                 'font-weight': 'bold', "color": "#5078b4"},
                                {'if': {'column_id': 'CompanyScore'},
                                 'font-weight': 'bold', "color": "#5078b4"},
                                {'if': {'column_id': 'Post'},
                                 'width': '30%'},
                                {'if': {'column_id': 'Candidate job title'},
                                 'width': '30%'},
                                {'if': {'column_id': 'Company type'},
                                 'width': '10%'}

                            ]
                        ),

                        # dbc.Table.from_dataframe(
                        #
                        #     subset_rs, striped=True, bordered=False, hover=True, index=False,
                        #     color='light',
                        #     size='sm'
                        #
                        #
                        # )

                    ]
                    )

                ], color="light", style={"width": "100%"})

            cards.append(html.Div([dbc.Row(dbc.Col(card, width={"size": 12})), html.Br()], style={"margin-left": "10px", "margin-right": "10px"}))

        return [cards, False]
    return[html.Div(), False]

if __name__ == "__main__":
    # app.run_server(debug=True, port=8052)
    # app.run_server(port=8085)
    ctrl.folder = None
    print("Running the app...")
    serve(app.server, host="0.0.0.0", port=8084)


import operator
from typing import List, Dict
from data.message import Message  # pylint: disable=import-error
from data.flow import Flow  # pylint: disable=import-error
from utils.utils import Utils  # pylint: disable=import-error

class Trace:

    def __init__(self, messages: List[Message]):
        self.logger = Utils.get_logger()
        self.messages: List[Message] = messages
        self.flows: Dict[str, Flow] = {}
        self.data_hist = {}
        self.id_hist = {}
        self.ids = []
        self.first_time = self.messages[0].timestamp
        self.last_time = self.messages[-1].timestamp
        self.logger.debug(f"TraceManager: length of the trace is: {self.get_trace_length()}")
        self.speed_id = int('0x410', 16)
        self.revolution_id = int('0x110', 16)

        # for infected_traces
        self.is_infected = False
        self.first_attack_time = None
        self.last_attack_time = None
        self.malicious_id = None

        # perform housekeeping
        #self.calculate_statistics()
        self.normalize_timestamps()

    def _separate_messages(self):
        if self.messages is None:
            error = "Messages parameter not set in FlowSeparator"
            self.logger.error(error)
            raise Exception(error)

        for msg in self.messages:
            if str(msg.id) in self.flows:
                self.flows[str(msg.id)].add_message(msg)
            else:
                self.flows[str(msg.id)] = Flow(msg)

        for flow in self.flows.values():
            flow.calculate_period()

    def calculate_statistics(self):

        self.logger.debug("Calculating statistics!")

        counter = 0
        len_sum = 0
        time_sum = 0
        time_counter = 0

        for msg in self.messages:

            counter += 1
            len_sum += msg.dlc

            if not self.first_time:
                self.first_time = msg.timestamp

            if self.last_time:
                time_sum += msg.timestamp - self.last_time
                time_counter += 1

            self.last_time = msg.timestamp

            for data_byte in msg.data:
                if data_byte in self.data_hist:
                    self.data_hist[data_byte] += 1
                else:
                    self.data_hist[data_byte] = 1

            if msg.id in self.id_hist:
                self.id_hist[msg.id] += 1
            else:
                self.id_hist[msg.id] = 1

            self.ids.append(msg.id)

        # create unique list
        self.ids = list(set(self.ids))

    def normalize_timestamps(self):
        self.first_time = self.messages[0].timestamp
        for message in self.messages:
            message.timestamp -= self.first_time
        self.first_time = self.messages[0].timestamp
        self.last_time = self.messages[-1].timestamp

    def get_number_of_error_frames(self):
        counter = 0
        for msg in self.messages:
            if msg.is_error_frame:
                counter += 1
        return counter

    def get_number_of_remote_frames(self):
        counter = 0
        for msg in self.messages:
            if msg.is_remote_frame:
                counter += 1
        return counter

    def get_ids(self):
        hex_ids = [str(hex(a)) for a in self.ids]
        hex_ids.sort()
        return hex_ids

    def get_number_of_ids(self):
        return len(self.ids)

    def get_trace_length(self):
        return (self.messages[-1].timestamp - self.messages[0].timestamp) / self.messages[0].timestamp_constant

    def get_speed_signal(self):

        speed_values = []
        time_values = []

        for i in range(0, len(self.messages)):
            message = self.messages[i]
            if message.id == self.speed_id:
                try:
                    speed = int.from_bytes(message.data[1:3], 'big')
                except ValueError:
                    self.logger.error("Value error during speed signal interpretation")
                    return None, None
                speed = speed / 100  # speed converted to km/h
                speed_values.append(speed)
                time_values.append(message.get_timestamp_in_seconds())

        return time_values, speed_values

    def get_revolution_signal(self):
        engine_revolution_values = []
        time_values = []

        for i in range(0, len(self.messages)):
            message = self.messages[i]
            if message.id == self.revolution_id:
                try:
                    engine_revolution = int.from_bytes(message.data[1:3], 'big', signed=False)
                except ValueError:
                    self.logger.error("Value error during revolution signal interpretation")
                    return None, None
                engine_revolution = engine_revolution / 4  # speed converted to km/h
                engine_revolution_values.append(engine_revolution)
                time_values.append(message.get_timestamp_in_seconds())

        return time_values, engine_revolution_values

    def detect_injection_parameters(self, attack:Dict):
        # malicious trace after injection attack determines its own attack parameters
        self.last_attack_time = attack['last_attack_time']
        self.malicious_id = hex(int(attack['id'], 16))
        inter_attack_time = attack['attack_inter_message_time']
        attacked_messages: List[Message] = list(filter(lambda m: m.id == int(attack['id'], 16), self.messages))

        for i in range(0, len(attacked_messages) - 1):

            # skip until rougly at the right time
            if attacked_messages[i].get_timestamp_in_seconds() < (attack['first_attack_time'] - 1):
                continue

            if attacked_messages[i + 1].get_timestamp_in_seconds() - attacked_messages[i].get_timestamp_in_seconds() < inter_attack_time * 1.2:
                self.first_attack_time = attacked_messages[i + 1].get_timestamp_in_seconds()
                self.logger.debug(f"First attack time for trace: {self.first_attack_time}")
                break

        if self.first_attack_time is None:
            self.logger.debug(f"First attack time could not be determined.")

        else:
            for i in range(0, len(attacked_messages) - 1):

                # skip until rougly at the right time
                if attacked_messages[i].get_timestamp_in_seconds() < (attack['last_attack_time'] - 0.2):
                    continue

                if attacked_messages[i + 1].get_timestamp_in_seconds() - attacked_messages[i].get_timestamp_in_seconds() > inter_attack_time * 3:
                    self.last_attack_time = attacked_messages[i].get_timestamp_in_seconds()
                    self.logger.debug(f"Last attack time for trace: {self.last_attack_time}")
                    break
            self.logger.debug(f"Attack parameters successfully determined.")

    def print_most_data_byte_statistics(self):
        max_value=0
        max_key=-1
        for key, value in self.data_hist.items():
            if value > max_value:
                max_value=value
                max_key=key
        print(f"Most frequent first data byte : {max_key}")
        print(
            f"Data first byte sorted histogram: {sorted(self.data_hist.items(), key=operator.itemgetter(1), reverse=True)}")

    def print_id_statistics(self):
        max_value=0
        max_key=""

        for key, value in self.id_hist.items():
            if value >= max_value:
                max_value=value
                max_key=max_key + str(hex(key)) + ", "

        printable_histogram=[(hex(item[0]), item[1]) for item in sorted(
            self.id_hist.items(), key=operator.itemgetter(1), reverse=True)]

        print(f"Most frequent id(s) : {max_key}")
        print(f"Id sorted histogram: {printable_histogram}")

    def print_example_data(self):
        for i in range(0, 10):
            print(self.messages[i])


# -*- coding: utf-8 -*-
"""
  Created on Fri Dec  6 07:55:28 2019
  二叉树
  @author: 刘瑜
  源代码文件是：U3Build'BinaryTree.py
"""
import numpy as np
class Node():                            #定义节点类
    def __init__(self,data=''):
        self.data=data                  #节点数值
        self.left=None                  #左子节点
        self.right=None                 #右子节点
    def __str__(self):                  #隐性读取当前节点方法
        return str(self.data)           #返回当前节点值

class BuildTree():
    def __init__(self,firstData):
        self.rootNode=Node(firstData)   #树的根节点,默认数据值为空
    def addNodes(self,NewDatas): #有序树增加节点,NewDatas为列表，前提要求数据已经排序
        Datalength=len(NewDatas)+1      #1为根节点
        depth=np.floor(np.log2(Datalength))+1  #求树的深度
        i=2
        stock=[self.rootNode]           #记录根节点地址
        while i<=depth:                 #处理每层树的节点
            currNN=2**(i-1)             #当前层最大节点数
            j=0
            while j<currNN:             #对当前层次的增加节点，直到加满
               curr=stock[0]            #获取当前节点地址
               j+=1
               if NewDatas:             #列表不为空时，弹出左边的元素
                   data=NewDatas.pop(0) #在列表里删除进入新节点的元素
               else:
                   break;               #最后一层节点必须考虑列表提供值不是满节点的情况
               Node1=Node(data)         #生成新节点
               print('入节点数%d'%(data))
               if j%2==0:               #j=1增加左节点，j=2增加右节点
                  curr.right=Node1      #当前节点增加右子节点
                  stock.pop(0)         #去掉最前面的节点地址
                  stock.append(Node1)  #最右右节点地址
               else:
                  curr.left=Node1      #当前节点增加左子节点
                  stock.append(Node1)  #最右左节点地址
            i+=1                       #树层加1
line1=[1,20,30,40,50,60,70,80]         #节点的数值
B1=BuildTree(line1[0])                 #建立带根节点的二叉树实例
B1.addNodes(line1[1:])                 #从第2节点开始构建树
#===================================
def preoder(root):                     #先序遍历，递归遍历
    p1=[]
    if root:                           #非空节点
        p1.append(root.data)
        p1+= preoder(root.left)        #递归调用左节点
        p1+= preoder(root.right)       #递归调用右节点
    return p1                          #返回列表
L1=preoder(B1.rootNode)
print(L1)
#=====================================
def middle(root):                     #中序遍历，递归遍历
    p1=[]
    if root:                           #非空节点
        p1+= middle(root.left)        #递归调用左节点
        p1.append(root.data)
        p1+= middle(root.right)       #递归调用右节点
    return p1                          #返回列表
L1=middle(B1.rootNode)
print(L1)
#=====================================
def post(root):                     #后序遍历，递归遍历
    p1=[]
    if root:                           #非空节点
        p1+= post(root.left)        #递归调用左节点
        p1+= post(root.right)       #递归调用右节点
        p1.append(root.data)
    return p1                          #返回列表
L1=post(B1.rootNode)
print(L1)
#====================================
def level(root):
    q1=[root.data,root.left, root.right]#存放数据，左右节点地址
    p1=[]                               #记录节点的数值
    while q1:
        em= q1.pop(0)                   #从列表跳出一个元素
        if em:
            if isinstance(em,Node):       #判断元素是节点地址
                q1.append(em.data)        #把节点里的数值放入列表
                q1.append(em.left)        #把节点里的左子节点地址放入列表
                q1.append(em.right)       #把节点里的右子节点地址放入列表
            else:
                p1.append(em)            #把节点数据放入列表
    return p1
L1=level(B1.rootNode)
print(L1)


from library.app import app
import library.loan as loan
import flask
from flask import jsonify

@app.route('/api/loans', methods=['GET'])
def get_all_loans():
    """
    """
    return jsonify(loan.get_all())

@app.route('/api/loans', methods=['POST'])
def create_loan():
    put_data = flask.request.get_json()
    if put_data is None:
        response = jsonify({'msg': 'Missing json data in put request.'})
        response.status_code = 400
        return response
    elif 'user_id' not in put_data:
        response = jsonify({'msg': 'Missing user_id in put request.'})
        response.status_code = 400
        return response
    elif 'book_id' not in put_data:
        response = jsonify({'msg': 'Missing book_id in put request.'})
        response.status_code = 400
        return response

    try:
        loan_id = loan.add(put_data['book_id'], put_data['user_id'])
        return jsonify(loan.get(loan_id))
    except loan.LoanNotAllowed as err:
        response = jsonify({'msg': str(err)})
        response.status_code = 400
        return response

@app.route('/api/loans/<int:loan_id>', methods=['GET'])
def get_loan(loan_id):
    """
    """
    return jsonify(loan.get(loan_id))

@app.route('/api/loans/<int:loan_id>', methods=['DELETE'])
def remove_loan(loan_id):
    """
    """
    return jsonify(loan.remove(loan_id))


import re
import string
import json
import sys
import pprint

items = {
    "scope": "source.lua",

    "completions": [ ]
}

if len(sys.argv) != 2:
  print("Usage: "+ sys.argv[0] + " <raw-completions>")
  sys.exit(1)

fh = open(sys.argv[1])

for line in fh.readlines():
  typeDesc = "unknown"
  line = line.strip()
  # print(line)
  if line.find(':') != -1:
    # We have a type member, since we can't know what the object is called,
    # complete from the semi-colon only
    line = line.partition(':')[2]

  if line.find("\t") != -1:
    # We have a type description after a tab
    typeDesc = line.partition("\t")[2]
    line = line.partition("\t")[0]

  argListMatch = re.search("\((.*)\)", line)

  if argListMatch != None:
    argsString = argListMatch.groups()[0]
    typeDesc = argsString.strip() if typeDesc is "unknown" else typeDesc
    funcName = line.replace("("+argsString+")", "")
    funcName = funcName.strip()
    args = re.findall("(\[.*?\]|[^\[,]*)", argsString)
    # print("   funcName", funcName)
    # print("   argsString", argsString)
    # print("   args", args)
    argCount = 1
    stCompArgs = ""
    for arg in args:
      arg = arg.strip()
      if arg == "":
        continue
      # if the arg is not optional and includes a comma, add a comma
      if not arg.startswith("[,"):
        stCompArgs += ","
      stCompArgs += " ${"+str(argCount)+":"+arg+"}"
      argCount += 1
    stCompArgs = stCompArgs.lstrip(",");
    # print({"trigger": "{0}()\t{1}".format(funcName, typeDesc), "contents": "{0}({1} )".format(funcName, stCompArgs)})
    items['completions'].append({"trigger": "{0}()\t{1}".format(funcName, typeDesc), "contents": "{0}({1} )".format(funcName, stCompArgs)})
  else:
    items['completions'].append({"trigger": "{0}\t{1}".format(line, typeDesc), "contents": line})

# pp = pprint.PrettyPrinter(indent = 2)
# pp.pprint(items)
# The string replacements reduce the indented JSON to one item per line
print(json.dumps(items, indent = 2).replace('{\n', '{').replace('", \n', '", ').replace('"\n', '"').replace('  ', ' '))


# -*- coding: utf-8 -*-
"""
Created on Sun Jul 17 06:38:49 2022

@author: eliem
"""

class Roman:

    global int_input_str

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

    def driver(self):
        def to_zip_lists(list_1,list_2):
            return list(zip(list_1,list_2))

        def digit_heads_str():
            int_input_str = str(self.int_input)
            for i in range(len(int_input_str)):
                digit_head = int_input_str[i]
                digit_head_list_str.append(digit_head)
            return digit_head_list_str

        def digit_heads_int():
            int_input_str = str(self.int_input)
            for i in range(len(int_input_str)):
                digit_head = int(int_input_str[i])
                digit_head_list_int.append(digit_head)
            return digit_head_list_int

        def number_of_zeros():
            for i in range(len(digit_head_list_str)-1,-1,-1):
                num_of_zeros_list.append(i)
            return num_of_zeros_list

        def value_of_num_breakdown():
            value_of_digit_head_to_num_of_zeros = to_zip_lists(digit_head_list_str,num_of_zeros_list)
            for i in range (len(value_of_digit_head_to_num_of_zeros)):

                v = 10 ** value_of_digit_head_to_num_of_zeros[i][1]
                values_breakdown.append(v)
            return values_breakdown

        def components_of_num():
            value_of_digit_head_to_factor_of_10_str = to_zip_lists(digit_head_list_str,values_breakdown)
            for i in range(len(value_of_digit_head_to_factor_of_10_str)):
                respective_values = int(value_of_digit_head_to_factor_of_10_str[i][0]) * value_of_digit_head_to_factor_of_10_str[i][1]
                components_list.append(respective_values)
            return components_list

        def filtration_lists():
            for i in range(0,9,1):
                if i not in range(4,8):
                    rn_head.append(i+1)
                else:
                    rn_middle.append(i+1)

        def rn_head_or_middle():
            value_of_digit_head_to_factor_of_10_int = to_zip_lists(digit_head_list_int,values_breakdown)
            for i in range(len(value_of_digit_head_to_factor_of_10_int)):
                if value_of_digit_head_to_factor_of_10_int[i][0] in rn_head:
                    trial_list.append('head')
                else:
                    trial_list.append('middle')
            return trial_list

        def rn_digit_first_digit_of_rn_block():

            def rn_digit_first_digit_head():

                for j in range(len(rn_symbols_head_by_zeros)):
                    if rn_head_or_middle_list[i][0] == 'head' and rn_head_or_middle_list[i][1] == rn_symbols_head_by_zeros[j][1]:
                        rn_block_head.append(rn_symbols_head_by_zeros[j])
                return rn_block_head

            def rn_digit_first_digit_middle():

                for j in range(len(rn_symbols_middle_by_zeros)):
                    if rn_head_or_middle_list[i][0] == 'middle'and rn_head_or_middle_list[i][1] == rn_symbols_middle_by_zeros[j][1]:
                        rn_block_middle.append(rn_symbols_middle_by_zeros[j])
                return rn_block_middle
            rn_head_or_middle_list = to_zip_lists(trial_list,num_of_zeros_list)
            for i in range(len(rn_head_or_middle_list)):
                if rn_head_or_middle_list[i][0] == 'head':
                    call_inner_fun_1 = rn_digit_first_digit_head()

                else:
                    call_inner_fun_2 = rn_digit_first_digit_middle()

        def reorder_list():
            rn_head_or_middle_list = to_zip_lists(trial_list,num_of_zeros_list)
            list_with_symbol_head = rn_block_head + rn_block_middle
            for j in range(len(rn_head_or_middle_list)):
                for i in range(len(list_with_symbol_head)):
                    if list_with_symbol_head[i][1] == rn_head_or_middle_list[j][1]:
                        list_with_symbol_head_pair.append(list_with_symbol_head[i])
                        list_with_symbol_head_final.append(list_with_symbol_head[i][0])

        def director():

            def for_val_1_3():
                for i in range(len(value_of_digit_head_to_factor_of_10_int)):
                    if value_of_digit_head_to_factor_of_10_int[i][0] <= 3:
                        rn_block_1_to_3 = list_with_symbol_head_final[i] * value_of_digit_head_to_factor_of_10_int[i][0]
                        rn_blocks_list.append(rn_block_1_to_3)
                return rn_blocks_list

            def for_val_4():
                for i in range(len(value_of_digit_head_to_factor_of_10_int)):
                    for k in range(len(rn_symbols_by_zeros)):
                        if value_of_digit_head_to_factor_of_10_int[i][0] == 4 and list_with_symbol_head_pair[i][1] == rn_symbols_by_zeros[k][1]:
                            rn_block_4 = rn_symbols_by_zeros[k][0] + rn_symbols_by_zeros[k+1][0]
                            rn_blocks_list.append(rn_block_4)
                            break
                return rn_blocks_list

            def for_val_5():
                for i in range(len(value_of_digit_head_to_factor_of_10_int)):
                    if value_of_digit_head_to_factor_of_10_int[i][0] == 5:
                        rn_block_5 = list_with_symbol_head_final[i]
                        rn_blocks_list.append(rn_block_5)
                return rn_blocks_list

            def for_val_6_8():
                for i in range(len(value_of_digit_head_to_factor_of_10_int)):
                    for k in range(len(rn_symbols_by_zeros)):
                        if 6 <= value_of_digit_head_to_factor_of_10_int[i][0] <= 8:
                            if list_with_symbol_head_pair[i][1] == rn_symbols_by_zeros[k][1]:

                                rn_block_multiple = (value_of_digit_head_to_factor_of_10_int[i][0] - 5)
                                rn_block_6_8 = rn_symbols_by_zeros[k+1][0] + rn_block_multiple * rn_symbols_by_zeros[k][0]

                                rn_blocks_list.append(rn_block_6_8)
                                break

                return rn_blocks_list

            def for_val_9():
                def first_symbol():
                    value_of_digit_head_to_factor_of_10_int = to_zip_lists(digit_head_list_int,values_breakdown)
                    for i in range(len(value_of_digit_head_to_factor_of_10_int)):
                        for k in range(len(rn_symbols_by_zeros)):

                            if value_of_digit_head_to_factor_of_10_int[i][0] == 9:
                                if list_with_symbol_head_pair[i][1] == rn_symbols_by_zeros[k][1]:

                                    rn_block_9_symbol_1 = rn_symbols_by_zeros[k][0]
                                    rn_blocks_list_5_first_symbol.append(rn_block_9_symbol_1)

                                    break

                    return rn_blocks_list_5_first_symbol

                def second_symbol():
                    for i in range(len(rn_blocks_list_5_first_symbol)):
                        for k in range(len(rn_symbols_by_zeros)):
                            if rn_blocks_list_5_first_symbol[i] == rn_symbols_by_zeros[k][0]:
                                rn_block_9_symbol_2 = rn_symbols_by_zeros[k+2][0]
                                rn_blocks_list_5_second_symbol.append(rn_block_9_symbol_2)
                    return rn_blocks_list_5_second_symbol

                call_inner_fun_3 = first_symbol()
                call_inner_fun_4 = second_symbol()

                concat_func = lambda x,y: x + "" + str(y)
                rn_block_9 = list(map(concat_func,rn_blocks_list_5_first_symbol,rn_blocks_list_5_second_symbol))
                for i in rn_block_9:
                    rn_blocks_list.append(i)
                return rn_blocks_list

            value_of_digit_head_to_factor_of_10_int = to_zip_lists(digit_head_list_int,values_breakdown)

            for i in range(len(value_of_digit_head_to_factor_of_10_int)):
                if value_of_digit_head_to_factor_of_10_int[i][0] <= 3:
                    call_inner_fun_1 = for_val_1_3()
                elif value_of_digit_head_to_factor_of_10_int[i][0] == 4:
                    call_inner_fun_2 = for_val_4()
                elif value_of_digit_head_to_factor_of_10_int[i][0] == 5:
                    call_inner_fun_3 = for_val_5()
                elif value_of_digit_head_to_factor_of_10_int[i][0] >= 6 and value_of_digit_head_to_factor_of_10_int[i][0] <= 8:
                    call_inner_fun_4 = for_val_6_8()
                else:
                    call_inner_fun_5 = for_val_9()

        def reorder_final_list():
            for i in range(len(list_with_symbol_head_pair)):
                    for j in range(len(rn_blocks_list)):
                        if list_with_symbol_head_pair[i][0] == rn_blocks_list[j][0]:
                            final_list.append(rn_blocks_list[j])
            return final_list

        rn_symbols = ['I','V','X','L','C','D','M']
        rn_values = [1,5,10,50,100,500,1000]

        rn_symbols_head = ['I','X','C','M']
        rn_symbols_head_by_zeros = [0,1,2,3]
        rn_symbols_to_digit_head_list = ['head','head','head','head']

        rn_symbols_middle = ['V', 'L', 'D',]
        rn_symbols_middle_by_zeros = [0,1,2]
        rn_symbols_to_digit_middle_list = ['middle','middle','middle']

        rn_symbols = ['I','V','X','L','C','D','M']
        rn_head_and_middle_list = ['head','middle','head','middle','head','middle','head']
        rn_symbols_head_and_middle_by_zeros_list = [0,0,1,1,2,2,3]

        rn_sym_to_value = to_zip_lists(rn_symbols,rn_values)

        rn_symbols_head_by_zeros = to_zip_lists(rn_symbols_head,rn_symbols_head_by_zeros)
        rn_symbols_middle_by_zeros = to_zip_lists(rn_symbols_middle,rn_symbols_middle_by_zeros)

        rn_symbols_to_digit_head = to_zip_lists(rn_symbols_head,rn_symbols_to_digit_head_list)
        rn_symbols_to_digit_middle_list = to_zip_lists(rn_symbols_middle,rn_symbols_to_digit_middle_list)

        rn_head_and_middle = to_zip_lists(rn_symbols,rn_head_and_middle_list)
        rn_symbols_head_and_middle_by_zeros = to_zip_lists(rn_head_and_middle_list,rn_symbols_head_and_middle_by_zeros_list)

        rn_symbols_by_zeros = to_zip_lists(rn_symbols,rn_symbols_head_and_middle_by_zeros_list)

        digit_head_list_str = []
        digit_head_list_int = []
        num_of_zeros_list = []
        values_breakdown = []
        components_list = []

        rn_head = []
        rn_middle = []

        trial_list = []
        rn_block_head = []
        rn_block_middle = []
        list_with_symbol_head_pair = []
        list_with_symbol_head_final = []

        rn_blocks_list_5_first_symbol = []
        rn_blocks_list_5_second_symbol = []

        rn_blocks_list = []

        final_list = []

        call_fun_1 = digit_heads_str()
        call_fun_2 = digit_heads_int()
        call_fun_3 = number_of_zeros()
        call_fun_4 = value_of_num_breakdown()
        call_fun_5 = components_of_num()
        call_fun_6 = filtration_lists()
        call_fun_7 = rn_head_or_middle()

        call_fun_8 = rn_digit_first_digit_of_rn_block()
        call_fun_9 = reorder_list()
        call_fun_10 = director()

        rn_blocks_list = list(set(rn_blocks_list))

        call_fun_11 = reorder_final_list()

        int_input_str = str(self.int_input)
        value_of_digit_head_to_num_of_zeros = to_zip_lists(digit_head_list_str,num_of_zeros_list)
        value_of_digit_head_to_factor_of_10_str = to_zip_lists(digit_head_list_str,values_breakdown)
        value_of_digit_head_to_factor_of_10_int = to_zip_lists(digit_head_list_int,values_breakdown)

        rn_head_or_middle_list = to_zip_lists(trial_list,num_of_zeros_list)
        list_with_symbol_head = rn_block_head + rn_block_middle

        result = ''.join(final_list)

        return result

integer_to_roman = Roman(3999)
integer_to_roman.driver()
b = integer_to_roman.driver()
print(b)


"""
Validate a face recognizer on the "Labeled Faces in the Wild"
(http://vis-www.cs.umass.edu/lfw/).
Embeddings are calculated using the pairs from http://vis-www.cs.umass.edu/lfw/pairs.txt and the ROC curve
is calculated and plotted...
"""
import numpy as np
from ..datagen.generator import facematch_datagenerator
from deep_insight_face.datagen.generator import triplet_datagenerator
import os
from typing import Any
from sklearn import metrics
from scipy.optimize import brentq
from scipy import interpolate
from csv import writer
from . import utility

class TripletEvaluate:
    def __init__(
        self,
        emd_model, image_paths, pairs,
    ) -> None:
        self.emd_model = emd_model
        self.image_paths = image_paths
        self.pairs = pairs

    def __call__(
        self,
        batch_size, nrof_folds, distance_metric,
        subtract_mean=False,
        use_fixed_image_standardization=False,
        use_image_aug_random=False,
        save_output_detail=False
    ):
        # Run forward pass to calculate embeddings

        # embedding_size = int(emd_model.get_shape()[1])
        embedding_size = 128
        generator = triplet_datagenerator(
            self.image_paths, self.pairs,
            do_augment=True,
            batch_size=batch_size,
            target_size=(160, 160),
            n_channels=3,
        )

        nrof_images = len(generator)
        emb_arr = np.zeros((nrof_images, embedding_size))
        lab_arr = np.zeros((nrof_images,))
        paths_arr = []
        idx = 0
        for X_batch, y in next(generator):
            lab = np.arange(idx, idx + len(y))
            idx += len(y)
            emb = self.emd_model.predict_on_batch(X_batch)
            lab_arr[lab] = y
            emb_arr[lab, :] = emb
            paths_arr += generator.pairs[lab]

        assert np.array_equal(lab_arr, np.arange(nrof_images)) is True, \
            'Wrong labels used for evaluation, possibly caused by training examples left in the input pipeline'
        tpr, fpr, accuracy, f1scores, val, val_std, far = utility.evaluate(
            emb_arr, lab_arr, nrof_folds=nrof_folds, distance_metric=distance_metric, subtract_mean=subtract_mean)

        print('Accuracy: %2.5f+-%2.5f' % (np.mean(accuracy), np.std(accuracy)))
        print('Validation rate: %2.5f+-%2.5f @ FAR=%2.5f' % (val, val_std, far))
        print("F1 Score: %2.5f+-%2.5f" % (np.mean(f1scores), np.std(f1scores)))
        auc = metrics.auc(fpr, tpr)
        print('Area Under Curve (AUC): %1.3f' % auc)
        eer = brentq(lambda x: 1. - x - interpolate.interp1d(fpr, tpr, fill_value="extrapolate")(x), 0., 1.)
        print('Equal Error Rate (EER): %1.3f' % eer)

        print('>>>> ============== >>>>')
        if save_output_detail:
            csv_out = result_to_csv(emb_arr, lab_arr, paths_arr, tpr, fpr,
                                    accuracy, f1scores, val, val_std, far)
            csv_out(0.3)

class SiameseEvaluate:
    def __init__(self, emd_model, image_paths, pairs,) -> None:
        self.emd_model = emd_model
        self.image_paths = image_paths
        self.pairs = pairs

    def __call__(self, *args: Any, **kwds: Any) -> Any:
        pass

class result_to_csv:
    def __init__(self,
                 emb_arr, lab_arr, paths_arr,
                 tpr, fpr, accuracy, f1scores, val, val_std, far) -> None:
        self.emb_arr, self.lab_arr, self.paths_arr = emb_arr, lab_arr, paths_arr
        self.tpr = tpr
        self.fpr = fpr
        self.accuracy = accuracy
        self.f1scores = f1scores
        self.val = val
        self.val_std = val_std
        self.far = far

    def __call__(self, threshold=0.5, out=None) -> Any:
        outname, ext = os.path.splitext(out)
        result_csv_name = f"{outname}-{threshold}.{ext}"
        results = self.__get_distances__(threshold, result_csv_name)
        return results

    def __get_distances__(self, threshold, result_csv_name) -> Any:
        # TODO: Fix this method
        print('Calculating features for images to check TP OR FN')
        # TP_FN_dict = {}
        with open(result_csv_name, 'w') as csv_file:
            csv_writer = writer(csv_file)
            results = np.array([[0, 0],
                                [0, 0]], dtype=np.int)

            distances = utility.get_emd_distance(self.emb_arr[0], self.emb_arr[1], distance_metric=0)
            results[1][1] += 1
            row = [paths[0].split("/")[-1], paths[1].split("/")[-1], distance, "same", TP_or_FN]
            csv_writer.writerow(row)

            utility.print_confusion_matrix(results, threshold)
        return results


from datetime import datetime

import scrapy
import ast
import logging
from ..scrapy_logger_utils import set_scrapy_logger

class ArticleSpider(scrapy.Spider):
    """
    An article scraper for all the available articles in the griddynamics domain.
        For each article, it scraps:
        1) title,
        2) url to full version,
        3) first 160 symbols of text,
        4) publication date,
        5) authors (full names),
        6) tags.
    """
    name = "articles"

    start_urls = []

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        x = ast.literal_eval(kwargs.pop('start_urls'))
        self.start_urls = x
        set_scrapy_logger(logging.WARNING)

    def parse(self, response, **kwargs):
        if 'author' in response.url:
            yield {
                'name': response.css('#woe > div.modalbg > div > div.row > div.titlewrp > h3').get(),
                'jobtitle': response.css('#woe > div.modalbg > div > div.row > div.titlewrp > p::text').get(),
                'linkedin': response.css('.modalbg > .linkedin::attr(href)').get(),
            }
        else:
            title = response.css('#wrap > h1::text').get()
            url = response.url
            text = "".join(response.css('#woe > section.postbody > div > p::text').getall())[:160]
            date = response.xpath('//*[@id="wrap"]/div/div[2]/text()').extract()[0][:-5].strip()
            date = datetime.strptime(date, '%b %d, %Y')

            raw_authors = response.css('#wrap > div > div.author.authors > div > span > a > span::text').getall()
            raw_authors = [author.strip() for author in raw_authors if author.strip() != ""]
            authors_urls = response.css('.goauthor::attr(href)').getall()

            authors = [(author, url) for author, url in zip(raw_authors, authors_urls)]
            tags = response.css('.post-tags > a::text').getall()

            logging.info(f"Scraped article: {title}")

            yield {
                'title': title,
                'url': url,
                'text': text,
                'date': date,
                'authors': authors,
                'tags': tags
            }


# https://leetcode.com/problems/edit-distance/
def minDistance(word1, word2):
    dp = [[0]*(len(word1)+1) for _ in range(len(word2)+1)]
    for i in range(1, len(word2)+1):
        dp[i][0] =  i
    for j in range(1, len(word1)+1):
        dp[0][j] = j
    for i in range(1, len(word2)+1):
        for j in range(1, len(word1)+1):
            if word1[j-1]==word2[i-1]:
                dp[i][j] = dp[i-1][j-1]
            else:
                dp[i][j] = min(dp[i][j-1]+1, dp[i-1][j]+1, dp[i-1][j-1]+1)
    return dp[len(word2)][len(word1)]

print(minDistance("intention", "execution"))


import subprocess
import logging
from upload_exceptions import FfmpegFileError

logger = logging.getLogger(__name__)

def create_thumbnails(video_file, folder):
    """ Creates thumbnails from video."""
    outfile = f'{folder}//out%02d.jpg'
    ffmpeg_args = ['ffmpeg',
                   # skip first 60 seconds
                   '-ss', '60',
                   '-i', video_file,
                   '-frames:v', '5',
                   '-vsync', 'vfr',
                   # one snapshot per minute of video
                   '-vf', 'fps=1/60',
                   outfile]
    process = subprocess.run(ffmpeg_args, capture_output=True)

    if process.returncode != 0:
        if process.stderr:
            logger.error(process.stderr)
        else:
            logger.error(process.stdout)
        raise RuntimeError('Ffmpeg failed to create thumbnails.')

def insert_watermark(input_file, out_file, image_path):
    """ Insert watermark on video."""
    ffmpeg_args = ['ffmpeg',
                   '-i', input_file,
                   '-i', image_path,
                   '-filter_complex', 'overlay=10:10',
                   '-crf', '18',
                   '-y', out_file]
    process = subprocess.run(ffmpeg_args, capture_output=True)

    if process.returncode != 0:
        if process.stderr:
            logger.debug(process.stderr)
        else:
            logger.debug(process.stdout)
        raise FfmpegFileError('Input file cannot be processed.')


import time
from datetime import datetime as dt

#This program will run in the background and during a certain time frame block certain, specified sites.

hosts_temp='hosts'
#Using the r allows us to escape escape characters
hosts_path=r'C:\Windows\System32\drivers\etc\hosts'
redirect = '127.0.0.1'
sites_that_kill_my_time = ['www.facebook.com', 'facebook.com', 'www.gmail.com', 'gmail.com']
#These 4 elements need their own respective lines on the host file and redirect IP
print(dt.now())

while True:
    #We are stating that if the time is between 9am and 5 pm on today
    if dt(dt.now().year, dt.now().month, dt.now().day, 9) < dt.now() < dt(dt.now().year, dt.now().month, dt.now().day, 17):
        print("These are my Working Hours: ")
# now we can load, read and write to the hosts file, using the r+ allows reading and writing to the file
        with open(hosts_path, 'r+') as file:
            content = file.read() # This will load the entire file
            for site in sites_that_kill_my_time:
                if site in content:
                    pass
                else:
                    file.write(redirect + ' ' + site + '\n')
    else:
        with open(hosts_path, 'r+') as file:
            content = file.readlines()
#The readlines() method will place the cursor at the end of the file.
# To bring the cursor back to the begining we use the seek() function and specify its placement.
            file.seek(0)
            for line in content:
# If item not there, append a new file host via writing a new file
                if not any(site in line for site in sites_that_kill_my_time):
                    file.write(line)
# truncate method will delete all things under the specified section
            file.truncate()
        print("Time to play!!!")
    time.sleep(600)


#!/usr/bin/python3
__author__ = "Ric Rodriguez"
__email__ = "therickyross2@gmail.com"
__project__ = "Thorium-DAQ"

import socket
import sys
from pyvisa import ResourceManager
import logging
import logging.handlers
import os

ERROR_BOARD_NOT_FOUND = -1
ERROR_BAD_COMMAND = -2
ERROR_LOST_BOARD_COMMS = -3

HOST_IP_ADDRESS = "0.0.0.0"
PORT = 10000

class SyslogBOMFormatter(logging.Formatter):
    def format(self, record):
        result = super().format(record)
        return "ufeff" + result

class Caen_control(object):
    """
    Class to control the CAEN psu over usb-serial
    """
    test = False

    def __init__(self):

        resource_manager = ResourceManager('@py')

        try:
            self.inst = resource_manager.open_resource(
                resource_manager.list_resources()[0]
            )
        except:
            print("Could not find")
            self.test = True
            return

        if "ok" in self.inst.query("$BD:0,CMD:MON,PAR:BDNAME").lower():
            print("Successfully connected to CAEN psu")
        else:
            sys.exit(ERROR_BOARD_NOT_FOUND)

    def send_command(self, command):
        if self.test:
            print(command)
            return "TEST MODE"
        return self.inst.query(command)

if __name__ == "__main__":

    # Set up loggers for DAQ
    handler = logging.handlers.SysLogHandler('/dev/log')
    formatter = SyslogBOMFormatter(logging.BASIC_FORMAT)
    handler.setFormatter(formatter)
    root = logging.getLogger()
    root.setLevel(os.environ.get("LOGLEVEL", "INFO"))
    root.addHandler(handler)

    # Set up socket server
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_address = (HOST_IP_ADDRESS, PORT)
    print("starting up on {} port {}".format(*server_address))
    sock.bind(server_address)
    sock.listen(1)

    caen = Caen_control()

    while True:
        print('waiting for connection')
        connection, client_address = sock.accept()
        try:
            print("connection from {}".format(client_address))
            while True:
                data = connection.recv(2048)
                print('recieved {!r}'.format(data))
                if data:
                    print('sending')
                    response = caen.send_command(data.decode())
                    connection.sendall(response.encode())
                else:
                    print("nodata")
                    break
        finally:
            connection.close()


import Graph_Sampling as sampling
import networkx as nx
import HeterogeneousNetwork as hn
import os, sys, random, time, math, json

def readLabels(file):
	labeledsNodes = []
	f = open(file, "r")
	for line in f:
		if len(line) == 0:
			continue
		node, y = line.split('\t')
		labeledsNodes.append(node)
	f.close()
	return labeledsNodes, len(y.split(','))

def add_labeleds(graph, labeledsNodes, sampled_subgraph):
	for node in labeledsNodes:
		for neighbor in graph[node]:
			if neighbor in sampled_subgraph:
				 sampled_subgraph.add_edge(node, neighbor)

def output_sample(output_file, sampling):
	file = open(output_file,"w")
	for edges in sampling.edges():
		file.write(edges[0] + "\t" + edges[1] + "\t1\n")
	file.close()

def chernoffBounds(N, c, alfa = 0.95, e = 0.15):
	alfa = math.log(1.0/alfa)
	p1 = e * N
	p2 = c * alfa
	p3 = alfa * alfa
	p4 = 2.0 * e * (N/c) * alfa
	chernoffBounds = p1 + p2 + c * math.sqrt(p3 + p4)
	chernoffBounds = math.floor(chernoffBounds)
	if chernoffBounds > N:
		return N
	else:
		return chernoffBounds

with open(sys.argv[1], "r") as read_file:
	params = json.load(read_file)

#create network
nt = hn.HeterogeneousNetwork()
nt.loadCSV(params['dataset'])

#read labels file
labeled_nodes, num_labels = readLabels(params['labels'])

output_dir = params['sampling_output_dir']
method = params['sampling_method']

#size of sampling
if len(sys.argv) > 2:
	size = int(sys.argv[2])
else:
	size = chernoffBounds(len(nt.net), num_labels)

#select random node
lista = nt.getNodes()
random.shuffle(lista)
node_seed = lista[0]

#sampled_subgraph = nx.Graph()
print(node_seed)
file_unreached = open(output_dir + "/unreached.txt","w")
reached = {}
count = 0
while len(reached) < len(nt.getNodes()):
	if method == 'SRW':
		object = sampling.SRW_RWF_ISRW()
		sampled_subgraph = object.random_walk_sampling_simple(nt.net,size,node_seed)
	elif method == 'RWF':
		arg = float(sys.argv[5])
		object = sampling.SRW_RWF_ISRW()
		sampled_subgraph = object.random_walk_sampling_with_fly_back(nt.net,size,arg,node_seed)
	elif method == 'ISRW':
		object = sampling.SRW_RWF_ISRW()
		sampled_subgraph = object.random_walk_induced_graph_sampling(nt.net,size,node_seed)
		sampled_subgraph = nt.net.subgraph(sampled_subgraph)
	elif method == 'SB':
		arg = int(sys.argv[5])
		object = sampling.Snowball()
		sampled_subgraph = object.snowball(nt.net,size,arg,node_seed)
	elif method == 'FF':
		object = sampling.ForestFire()
		sampled_subgraph = object.forestfire(nt.net,size,node_seed)
	elif method == 'MHRW':
		object = sampling.MHRW()
		sampled_subgraph = object.mhrw(nt.net,size,node_seed)
	elif method == 'Induced-MHRW':
		object = sampling.MHRW()
		sampled_subgraph = object.induced_mhrw(nt.net,size,node_seed)

	lista = list(sampled_subgraph.nodes())
	alcancou = False
	for node in lista:
		if node not in reached:
			reached[node] = True
			alcancou = True

	if alcancou:
		print("Nodes:", len(reached), '/', len(nt.getNodes()))
		print("After saimpling\t\tNodes:", len(sampled_subgraph.nodes),' Edges:', len(sampled_subgraph.edges()))
		count += 1
		add_labeleds(nt.net, labeled_nodes, sampled_subgraph)
		print("After add labeleds\tNodes:", len(sampled_subgraph.nodes),' Edges:', len(sampled_subgraph.edges()))
		print()
		output_sample(output_dir +'/' + str(count) + '.network', sampled_subgraph)
	else:
		print('unreached:', node_seed)
		reached[node_seed] = False
		file_unreached.write(node_seed + "\n")

	if node_seed:
		for node in nt.getNodes():
			if node not in reached:
				node_seed = node
				break
file_unreached.close()


import numpy as np
from one import parse_input, get_priority

def aggregate_list_n_by_n(data, n=3):
    d = np.array(data)
    d = np.reshape(d, (-1, n)).tolist()
    return d

def get_badges(data):
    badges = []
    for d in data:
        unique_chars = list(set(''.join(d)))
        for c in unique_chars:
            if (c in d[0]) and (c in d[1]) and (c in d[2]):
                badges.append(c)
                break
    return badges

if __name__ == '__main__':

    d = parse_input('./day3/input.txt')

    d = aggregate_list_n_by_n(d)

    d = get_badges(d)

    d = get_priority(d)

    print(d)
    print()
    print(sum(d))