#!/usr/bin/python3
from datetime import date, timedelta, datetime
from dateutil.relativedelta import relativedelta
import dash
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import pandas
from dash.dependencies import Input, Output

# data URL
consegne = 'https://raw.githubusercontent.com/italia/covid19-opendata-vaccini/master/dati/consegne-vaccini-latest.csv'
fascia_anagrafica = 'https://raw.githubusercontent.com/italia/covid19-opendata-vaccini/master/dati/platea.csv'
somministrazioni = 'https://raw.githubusercontent.com/italia/covid19-opendata-vaccini/master/dati/somministrazioni-vaccini-latest.csv'
decessi_contagi = 'https://raw.githubusercontent.com/pcm-dpc/COVID-19/master/dati-andamento-nazionale/dpc-covid19-ita-andamento-nazionale.csv'
decessi_contagi_regioni = 'https://raw.githubusercontent.com/pcm-dpc/COVID-19/master/dati-regioni/dpc-covid19-ita-regioni.csv'
population = 0

last_update = ''  # last update
max_prima_f = ''  # max first dose in 1day
tot_janssenf = ''  # tot only 1 dose format
tot_janssen = ''  # tot only 1 dose
month_last_day_vaccine = ''  # 70% population vaccine date
percent_mese = ''  # percentage
percent_mese_vaccine = ''
percent_mese_death = ''  # percentage death
percent_mese_vaccine_death = ''
pandas.options.mode.chained_assignment = None  # default='warn'

# read csv for url and get date
dc = pandas.read_csv(consegne)
ds = pandas.read_csv(somministrazioni)
ddc = pandas.read_csv(decessi_contagi)
ddcr = pandas.read_csv(decessi_contagi_regioni)
dfe = pandas.read_csv(fascia_anagrafica)
regions = ds['nome_area'].drop_duplicates().tolist()  # all regions

plotly_js_minified = ['https://cdn.plot.ly/plotly-basic-latest.min.js']
app = dash.Dash(__name__, external_scripts=plotly_js_minified,
                meta_tags=[{'name': 'viewport', 'content': 'width=device-width, initial-scale=0.8, maximum-scale=1.2, minimum-scale=0.5'}],
                requests_pathname_prefix='/vaccine/',
                routes_pathname_prefix='/vaccine/')
app.title = 'Dashboard Vaccini'
server = app.server

# chart config
chart_config = {'displaylogo': False, 'displayModeBar': False, 'responsive': True}

# slider buttons (1m, 3m, 6m, all)
slider_button = list([
    dict(count=1,
         label="1m",
         step="month",
         stepmode="backward"),
    dict(count=3,
         label="3m",
         step="month",
         stepmode="backward"),
    dict(count=6,
         label="6m",
         step="month",
         stepmode="backward"),
    dict(step="all")
])

# refresh data
def refresh_data():
    global today, last_update, max_prima_f
    global dc, ds, dfa, ddc, dfe, tot_dfe, ds_dosi
    global tot_prima_dose, tot_seconda_dose, tot_prima, tot_seconda, tot_covid, tot_with_covid
    global percent_mese_death, percent_mese
    # read csv for url and get date
    dc = pandas.read_csv(consegne)
    ds = pandas.read_csv(somministrazioni)
    ddc = pandas.read_csv(decessi_contagi)
    dfe = pandas.read_csv(fascia_anagrafica)
    today = date.today()

    # doses delivered
    dc = dc.groupby('data_consegna').agg({'numero_dosi': 'sum'}).reset_index()
    # doses administered
    ds_dosi = ds.groupby('data_somministrazione').agg({'prima_dose': 'sum', 'seconda_dose': 'sum', 'pregressa_infezione': 'sum'}).reset_index()

    ds_prime_dosi = ds_dosi.loc[ds_dosi['data_somministrazione'] == str(today), 'prima_dose']
    if len(ds_prime_dosi) == 0:
        last_update = date.today()
    else:
        last_update = date.today() - timedelta(days=1)

    # max first
    max_prima = int(max(ds_dosi['prima_dose']))
    max_prima_f = '{:,}'.format(max_prima).replace(',', '.')  # format max first dose
    # percentage death-positive
    date_format = "%Y-%m-%d"  # date format
    ora = datetime.strptime(str(today), date_format)
    mese = ora - relativedelta(months=1)
    # positive
    month_prima_p = ddc.loc[ddc['data'].between(str(mese)[:10], str(ora)[:10]), ['nuovi_positivi']].sum()
    month_pprima_p = ddc.loc[ddc['data'].between(str(mese - relativedelta(months=1))[:10], str(mese)[:10]), ['nuovi_positivi']].sum()
    percent_mese = round((int(month_prima_p) / month_pprima_p) * 100, 2)
    # death
    ddc['nuovi_decessi'] = ddc.deceduti.diff().fillna(ddc.deceduti)
    month_prima_d = ddc.loc[ddc['data'].between(str(mese)[:10], str(ora)[:10]), ['nuovi_decessi']].sum()
    month_pprima_d = ddc.loc[ddc['data'].between(str(mese - relativedelta(months=1))[:10], str(mese)[:10]), ['nuovi_decessi']].sum()
    percent_mese_death = round((int(month_prima_d) / month_pprima_d) * 100, 2)

    # first dose from the start
    tot_prima = ds_dosi.loc[ds_dosi['data_somministrazione'].between('2020-12-27', str(today)), ['prima_dose']].sum()
    tot_prima_dose = '{:,}'.format(int(tot_prima)).replace(',', '.')
    # second dose from the start
    tot_seconda = ds_dosi.loc[ds_dosi['data_somministrazione'].between('2020-12-27', str(today)), ['seconda_dose']].sum()
    tot_seconda_dose = '{:,}'.format(int(tot_seconda)).replace(',', '.')
    # with covid
    tot_covid = ds_dosi.loc[ds_dosi['data_somministrazione'].between('2020-12-27', str(today)), ['pregressa_infezione']].sum()
    tot_with_covid = '{:,}'.format(int(tot_covid)).replace(',', '.')
    # age
    dfa = ds.groupby('fascia_anagrafica').agg({'prima_dose': 'sum', 'seconda_dose': 'sum'}).reset_index()
    tot_dfe = dfe.groupby('fascia_anagrafica').agg({'totale_popolazione': 'sum'}).reset_index()

# dropdown
def get_dropdown_data():
    selections = []
    selections.append(dict(label='Dato Nazionale', value='Dato Nazionale'))
    for reg in regions:
        selections.append(dict(label=reg, value=reg))
    return selections

# total vaccine status
def vaccine_update():
    #refresh_data()
    global tot_janssen, tot_janssenf
    # percentage
    janssen = ds.loc[ds['fornitore'] == 'Janssen'].groupby('data_somministrazione').agg({'prima_dose': 'sum'}).reset_index()
    tot_janssen = janssen.loc[janssen['data_somministrazione'].between('2021-04-05', str(today)), ['prima_dose']].sum()
    prima = int(tot_prima) - int(tot_janssen)
    vaccinati = int(tot_seconda) + int(tot_janssen) + int(tot_covid)
    # percentage
    primadose = round((int(prima)/60360000)*100, 2)
    secondadose = round((int(vaccinati)/60360000)*100, 2)
    tjanssen = round((int(tot_janssen) / 60360000) * 100, 2)
    covid = round((int(tot_covid) / 60360000) * 100, 2)
    # percentage platea
    p_primadose = round((int(prima) / 50773718) * 100, 2)
    p_secondadose = round((int(vaccinati) / 50773718) * 100, 2)
    p_tjanssen = round((int(tot_janssen) / 50773718) * 100, 2)
    p_covid = round((int(tot_covid) / 50773718) * 100, 2)
    # formating
    tot_prima_dose = '{:,}'.format(int(prima)).replace(',', '.')
    tot_vaccinati_dose = '{:,}'.format(int(vaccinati)).replace(',', '.')
    tot_janssenf = '{:,}'.format(int(tot_janssen)).replace(',', '.')
    tot_covid_dosi = '{:,}'.format(int(tot_covid)).replace(',', '.')
    return html.Div([
        html.Div([
            html.Table([
                # Header
                html.Tr([
                    html.Td('Prima dose', style={'font-size': '14px'}),
                ]),
                # Body
                html.Tr([
                    html.Td(
                        html.H1(tot_prima_dose, style={'color': '#F5C05F', 'font-size': '45px'})
                    ),
                ]),
                # Percentage platea
                html.Tr([
                    html.Td(html.B(
                        '' + str(p_primadose) + '% della platea',
                        style={'color': '#F5C05F', 'font-size': '14px'}
                    ))
                ]),
                # Percentage
                html.Tr([
                    html.Td(html.B(
                        '' + str(primadose) + '% della popolazione',
                        style={'color': '#F5C05F', 'font-size': '14px'}
                    ))
                ]),
            ], className='table')
        ], className='container-3'),
        html.Div([
            html.Table([
                # Header
                html.Tr([
                    html.Td('Persone Vaccinate', style={'font-size': '14px'})
                ]),
                # Body
                html.Tr([
                    html.Td(
                        html.H1(tot_vaccinati_dose, style={'color': '#E83A8E', 'font-size': '45px'})
                    )
                ]),
                # Percentage platea
                html.Tr([
                    html.Td(html.B(
                        '' + str(p_secondadose) + '% della platea', style={'color': '#E83A8E', 'font-size': '14px'}
                    ))
                ]),
                # Percentage
                html.Tr([
                    html.Td(html.B(
                        '' + str(secondadose) + '% della popolazione', style={'color': '#E83A8E', 'font-size': '14px'}
                    ))
                ]),
            ], className='table')
        ], className='container-3'),
        html.Div([
            html.Div([
                html.Table([
                    # Header
                    html.Tr([
                        html.Td('Di cui con vaccino monodose', colSpan=2, style={'font-size': '14px'}),
                    ]),
                    # Body
                    html.Tr([
                        html.Td(
                            html.H1(tot_janssenf, style={'color': '#C93E7F', 'font-size': '30px'})
                        ),
                        html.Td([html.B(
                            '' + str(p_tjanssen) + '% della platea', style={'color': '#C93E7F', 'font-size': '12px'}
                        ), html.Br(), html.B(
                            '' + str(tjanssen) + '% della popolazione', style={'color': '#C93E7F', 'font-size': '12px'}
                        )]),
                    ]),
                ], className='table')
            ], className='container-1'),
            html.Div([
                html.Table([
                    # Header
                    html.Tr([
                        html.Td('Di cui con pregressa infezione', colSpan=2, style={'font-size': '14px'}),
                    ]),
                    # Body
                    html.Tr([
                        html.Td(
                            html.H1(tot_covid_dosi, style={'color': '#B33771', 'font-size': '30px'})
                        ),
                        html.Td([html.B(
                            '' + str(p_covid) + '% della platea', style={'color': '#B33771', 'font-size': '12px'}
                        ), html.Br(), html.B(
                            '' + str(covid) + '% della popolazione', style={'color': '#B33771', 'font-size': '12px'}
                        )]),
                    ]),
                ], className='table')
            ], className='container-1')
        ], className='container-3')
    ], className='container-1')

def vaccine_update_bar():
    #refresh_data()
    return html.Div([
        html.Div([
            dcc.Graph(
                figure={
                    'data': [go.Bar(x=[60360000, 50773718, int(tot_prima)-int(tot_janssen), int(tot_seconda)+int(tot_janssen)+int(tot_covid)],
                                    y=['Popolazione', 'Platea', 'Prima dose', 'Vaccinati'],
                                    orientation='h',
                                    marker_color=['#6181E8', '#5EAEFF', '#F5C05F', '#E83A8E'])
                             ],
                    'layout': {
                        'height': 250,  # px
                        'xaxis': dict(
                            rangeslider=dict(visible=False),
                            type=''
                        )
                    },
                },
                config=chart_config
            )
        ], className='bar')
    ], className='container-1')

# dropdown select
def dropdown_vaccine_daily():
    return html.Div([
        html.Div([
            dbc.Container([
                dbc.Row([
                    dbc.Col(
                        dcc.Dropdown(id='dropdown_vaccine_daily',
                                     options=get_dropdown_data(), clearable=False, searchable=False,
                                     persistence=True, persistence_type='session', value='Dato Nazionale'
                                     ), style={'margin-left': 'auto', 'margin-right': 'auto'}, width=12, lg=5,
                        className='mt-2')
                ])
            ])
        ])
    ])

# vaccine horozzonatal bar
@app.callback(
    Output('vaccine_daily', 'children'),
    [Input('dropdown_vaccine_daily', 'value')])
def vaccine_daily(regione):
    # total data
    if regione == 'Dato Nazionale':
        #refresh_data()
        tot_consegne = dc.loc[dc['data_consegna'].between('2020-12-27', str(today)), ['numero_dosi']].sum()
        tot_vaccini = int(tot_prima) + int(tot_seconda)
        # today data
        dc_dosi_consegnate = dc.loc[dc['data_consegna'] == str(today), 'numero_dosi']
        ds_prime_dosi = ds_dosi.loc[ds_dosi['data_somministrazione'] == str(today), 'prima_dose']
        ds_seconde_dosi = ds_dosi.loc[ds_dosi['data_somministrazione'] == str(today), 'seconda_dose']

        # check today data
        if len(dc_dosi_consegnate) == 0 and len(ds_prime_dosi) == 0 and len(ds_seconde_dosi) == 0:
            dc_dosi_consegnate = dc.loc[dc['data_consegna'] == str(date.today() - timedelta(days=1)), 'numero_dosi']
            ds_prime_dosi = ds_dosi.loc[ds_dosi['data_somministrazione'] == str(date.today() - timedelta(days=1)), 'prima_dose']
            ds_seconde_dosi = ds_dosi.loc[ds_dosi['data_somministrazione'] == str(date.today() - timedelta(days=1)), 'seconda_dose']
    else:
        dc1 = pandas.read_csv(consegne)
        ds1 = pandas.read_csv(somministrazioni)
        reg_ds1 = ds1.loc[ds1['nome_area'] == regione]
        ds_dosi1 = reg_ds1.copy().groupby('data_somministrazione').agg({'prima_dose': 'sum', 'seconda_dose': 'sum'}).reset_index()
        tot_prima1 = ds_dosi1.loc[ds_dosi1['data_somministrazione'].between('2020-12-27', str(today)), ['prima_dose']].sum()
        tot_seconda1 = ds_dosi1.loc[ds_dosi1['data_somministrazione'].between('2020-12-27', str(today)), ['seconda_dose']].sum()
        reg_dc1 = dc1.loc[dc1['nome_area'] == regione]
        dc_dosi1 = reg_dc1.copy().groupby('data_consegna').agg({'numero_dosi': 'sum'}).reset_index()

        # data
        tot_consegne = dc_dosi1.loc[dc_dosi1['data_consegna'].between('2020-12-27', str(today)), ['numero_dosi']].sum()
        tot_vaccini = int(tot_prima1) + int(tot_seconda1)
        # today data
        dc_dosi_consegnate = dc_dosi1.loc[dc_dosi1['data_consegna'] == str(today), 'numero_dosi']
        ds_prime_dosi = ds_dosi1.loc[ds_dosi1['data_somministrazione'] == str(today), 'prima_dose']
        ds_seconde_dosi = ds_dosi1.loc[ds_dosi1['data_somministrazione'] == str(today), 'seconda_dose']

        # check today data
        if len(dc_dosi_consegnate) == 0 and len(ds_prime_dosi) == 0 and len(ds_seconde_dosi) == 0:
            dc_dosi_consegnate = dc1.loc[dc1['data_consegna'] == str(date.today() - timedelta(days=1)), 'numero_dosi']
            ds_prime_dosi = ds_dosi1.loc[ds_dosi1['data_somministrazione'] == str(date.today() - timedelta(days=1)), 'prima_dose']
            ds_seconde_dosi = ds_dosi1.loc[ds_dosi1['data_somministrazione'] == str(date.today() - timedelta(days=1)), 'seconda_dose']

    ds_dosi_totali = 0
    tot_consegne = '{:,}'.format(int(tot_consegne)).replace(',', '.')
    tot_vaccini = '{:,}'.format(int(tot_vaccini)).replace(',', '.')

    # formatting data
    if len(dc_dosi_consegnate) == 0:
        dc_dosi_consegnate = 0
    else:
        dc_dosi_consegnate = '{:,}'.format(int(dc_dosi_consegnate)).replace(',', '.')
    if len(ds_prime_dosi) == 0:
        ds_prime_dosi = 0
        ds_dosi_totali = int(ds_prime_dosi)
    else:
        ds_dosi_totali = int(ds_prime_dosi)
        ds_prime_dosi = '{:,}'.format(int(ds_prime_dosi)).replace(',', '.')
    if len(ds_seconde_dosi) == 0:
        ds_seconde_dosi = 0
        ds_dosi_totali = ds_dosi_totali + int(ds_seconde_dosi)
    else:
        ds_dosi_totali = ds_dosi_totali + int(ds_seconde_dosi)
        ds_seconde_dosi = '{:,}'.format(int(ds_seconde_dosi)).replace(',', '.')

    if ds_dosi_totali != 0:
        ds_dosi_totali = '{:,}'.format(int(ds_dosi_totali)).replace(',', '.')

    return html.Div([
        # vaccine
        html.Div([
            html.Table([
                # Header
                html.Tr([
                    html.Td('Vaccini Consegnati', style={'font-size': '14px'}),
                ]),
                # Body
                html.Tr([
                    html.Td(
                        html.H1('+ '+str(dc_dosi_consegnate)+'', style={'color': '#29CF8A', 'font-size': '45px'})
                    )
                ]),
                # Yesterday
                html.Tr([
                    html.Td(html.B(
                        'Totali: '+str(tot_consegne), style={'color': '#29CF8A', 'font-size': '14px'}
                    ))
                ])
            ], className='table')
        ], className='container-4'),

        # doses
        html.Div([
            html.Table([
                # Header
                html.Tr([
                    html.Td('Dosi Somministrate', style={'font-size': '14px'}),
                ]),
                # Body
                html.Tr([
                    html.Td(
                        html.H1('+ ' + str(ds_dosi_totali) + '', style={'color': '#376FDB', 'font-size': '45px'})
                    )
                ]),
                # Yesterday
                html.Tr([
                    html.Td(html.B(
                        'Totali: ' + str(tot_vaccini), style={'color': '#376FDB', 'font-size': '14px'}
                    ))
                ])
            ], className='table')
        ], className='container-4'),

        # first doses
        html.Div([
            html.Table([
                # Header
                html.Tr([
                    html.Td('Prime Dosi', style={'font-size': '14px'}),
                ]),
                # Body
                html.Tr([
                    html.Td(
                        html.H1('+ ' + str(ds_prime_dosi) + '', style={'color': '#F5C05F', 'font-size': '45px'})
                    )
                ]),
                # Yesterday
                html.Tr([
                    html.Td(html.B(
                        'Totali: ' + str(tot_prima_dose), style={'color': '#F5C05F', 'font-size': '14px'}
                    ))
                ])
            ], className='table')
        ], className='container-4'),

        # vaccine
        html.Div([
            html.Table([
                # Header
                html.Tr([
                    html.Td('Persone Vaccinate (Due Dosi)', style={'font-size': '14px'})
                ]),
                # Body
                html.Tr([
                    html.Td(
                        html.H1('+ ' + str(ds_seconde_dosi) + '',
                                style={'color': '#E83A8E', 'font-size': '45px'})
                    )
                ]),
                # Yesterday
                html.Tr([
                    html.Td(html.B(
                        'Totali: ' + str(tot_seconda_dose), style={'color': '#E83A8E', 'font-size': '14px'}
                    ))
                ])
            ], className='table')
        ], className='container-4')
    ], className='container-1')

# vaccine horozzonatal bar
@app.callback(
    Output('vaccine_graph', 'children'),
    [Input('dropdown_vaccine_daily', 'value')])
# vaccine and doses graph
def vaccine_graph(regione):
    if regione == 'Dato Nazionale':
        #refresh_data()
        # vaccine
        ds_pfizer = ds.loc[ds['fornitore'] == 'Pfizer/BioNTech'].groupby('data_somministrazione').agg(
            {'prima_dose': 'sum', 'seconda_dose': 'sum'}).reset_index()
        ds_moderna = ds.loc[ds['fornitore'] == 'Moderna'].groupby('data_somministrazione').agg(
            {'prima_dose': 'sum', 'seconda_dose': 'sum'}).reset_index()
        ds_astra = ds.loc[ds['fornitore'] == 'Vaxzevria (AstraZeneca)'].groupby('data_somministrazione').agg(
            {'prima_dose': 'sum', 'seconda_dose': 'sum'}).reset_index()
        ds_janssen = ds.loc[ds['fornitore'] == 'Janssen'].groupby('data_somministrazione').agg(
            {'prima_dose': 'sum', 'seconda_dose': 'sum'}).reset_index()
    else:
        # vaccine
        ds1 = pandas.read_csv(somministrazioni)
        reg_ds1 = ds1.loc[ds1['nome_area'] == regione]
        ds_dosi1 = reg_ds1.copy().groupby('data_somministrazione').agg(
            {'prima_dose': 'sum', 'seconda_dose': 'sum', 'fornitore': 'last'}).reset_index()
        ds_pfizer = ds_dosi1.loc[ds_dosi1['fornitore'] == 'Pfizer/BioNTech'].groupby('data_somministrazione').agg(
            {'prima_dose': 'sum', 'seconda_dose': 'sum'}).reset_index()
        ds_moderna = ds_dosi1.loc[ds_dosi1['fornitore'] == 'Moderna'].groupby('data_somministrazione').agg(
            {'prima_dose': 'sum', 'seconda_dose': 'sum'}).reset_index()
        ds_astra = ds_dosi1.loc[ds_dosi1['fornitore'] == 'Vaxzevria (AstraZeneca)'].groupby('data_somministrazione').agg(
            {'prima_dose': 'sum', 'seconda_dose': 'sum'}).reset_index()
        ds_janssen = ds_dosi1.loc[ds_dosi1['fornitore'] == 'Janssen'].groupby('data_somministrazione').agg(
            {'prima_dose': 'sum', 'seconda_dose': 'sum'}).reset_index()
    return html.Div([
        dbc.Container([
            dbc.Row(
                dbc.Col(
                    dcc.Graph(
                        figure={
                            'data': [
                                {'x': ds_pfizer['data_somministrazione'],
                                 'y': ds_pfizer['prima_dose'] + ds_pfizer['seconda_dose'],
                                 'type': 'bar',
                                 'name': 'Pfizer',
                                 'marker': dict(color='#95A9DE')},
                                {'x': ds_moderna['data_somministrazione'],
                                 'y': ds_moderna['prima_dose'] + ds_moderna['seconda_dose'],
                                 'type': 'bar',
                                 'name': 'Moderna',
                                 'marker': dict(color='#395499')},
                                {'x': ds_astra['data_somministrazione'],
                                 'y': ds_astra['prima_dose'] + ds_astra['seconda_dose'], 'type': 'bar',
                                 'name': 'AstraZeneca',
                                 'marker': dict(color='#537BE0')},
                                {'x': ds_janssen['data_somministrazione'],
                                 'y': ds_janssen['prima_dose'] + ds_janssen['seconda_dose'],
                                 'type': 'bar',
                                 'name': 'Janssen',
                                 'marker': dict(color='#243561')},
                            ],
                            'layout': {
                                'barmode': 'stack',
                                'xaxis': dict(
                                    rangeselector=dict(buttons=slider_button),
                                    rangeslider=dict(visible=False),
                                    type='date'
                                ),
                                'legend': dict(
                                    orientation="h",
                                    xanchor="center",
                                    x=0.5,
                                    y=-0.2
                                )
                            }
                        },
                        config=chart_config
                    )
                )
            )
        ])
    ], className='container-2')

# vaccine horozzonatal bar
@app.callback(
    Output('dosi_graph', 'children'),
    [Input('dropdown_vaccine_daily', 'value')])
# vaccine and doses graph
def dosi_graph(regione):
    if regione == 'Dato Nazionale':
        #refresh_data()
        prima_seconda = ds.groupby('data_somministrazione').agg({'prima_dose': 'sum', 'seconda_dose': 'sum'}).reset_index()
    else:
        # vaccine
        ds1 = pandas.read_csv(somministrazioni)
        reg_ds1 = ds1.loc[ds1['nome_area'] == regione]
        prima_seconda = reg_ds1.copy().groupby('data_somministrazione').agg({'prima_dose': 'sum', 'seconda_dose': 'sum'}).reset_index()
    return html.Div([
            dbc.Container([
                dbc.Row(
                    dbc.Col(
                        dcc.Graph(
                            figure={
                                'data': [
                                    {'x': prima_seconda['data_somministrazione'], 'y': prima_seconda['prima_dose'],
                                     'type': 'bar',
                                     'name': 'Prima Dose',
                                     'marker': dict(color='#F5C05F')},
                                    {'x': prima_seconda['data_somministrazione'], 'y': prima_seconda['seconda_dose'],
                                     'type': 'bar',
                                     'name': 'Seconda Dose',
                                     'marker': dict(color='#78F5B3')},
                                ],
                                'layout': {
                                    'barmode': 'stack',
                                    'xaxis': dict(
                                        rangeselector=dict(buttons=slider_button),
                                        rangeslider=dict(visible=False),
                                        type='date'
                                    ),
                                    'legend': dict(
                                        orientation="h",
                                        xanchor="center",
                                        x=0.5,
                                        y=-0.2
                                    )
                                }
                            },
                            config=chart_config
                        )
                    )
                )
            ])
        ], className='container-2')

# dropdown select
def dropdown_vaccine_age_bar():
    return html.Div([
        html.Div([
            dbc.Container([
                dbc.Row([
                    dbc.Col(
                        dcc.Dropdown(id='dropdown_vaccine_age_bar',
                                     options=get_dropdown_data(), clearable=False, searchable=False,
                                     persistence=True, persistence_type='session', value='Dato Nazionale'
                                     ), style={'margin-left': 'auto', 'margin-right': 'auto'}, width=12, lg=5,
                        className='mt-2')
                ])
            ])
        ])
    ])

# vaccine # age
@app.callback(
    Output('vaccine_age_bar', 'children'),
    [Input('dropdown_vaccine_age_bar', 'value')])
def vaccine_age_bar(regione):
    if regione == 'Dato Nazionale':
        figure_age = {
            'data': [go.Bar(x=[int(dfa['prima_dose'][0])-int(dfa['seconda_dose'][0]), int(dfa['prima_dose'][1])-int(dfa['seconda_dose'][1]),
                               int(dfa['prima_dose'][2])-int(dfa['seconda_dose'][2]), int(dfa['prima_dose'][3])-int(dfa['seconda_dose'][3]),
                               int(dfa['prima_dose'][4])-int(dfa['seconda_dose'][4]), int(dfa['prima_dose'][5])-int(dfa['seconda_dose'][5]),
                               int(dfa['prima_dose'][6])-int(dfa['seconda_dose'][6]),
                               int(int(dfa['prima_dose'][7])-int(dfa['seconda_dose'][7])) + int(int(dfa['prima_dose'][8])-int(dfa['seconda_dose'][8]))],
                            y=['12-19', '20-29', '30-39', '40-49', '50-59', '60-69', '70-79', '80+'],
                            orientation='h',
                            marker_color='#F5C05F',
                            name='Prima Dose'
                            ),
                     go.Bar(x=[dfa['seconda_dose'][0], dfa['seconda_dose'][1], dfa['seconda_dose'][2],
                               dfa['seconda_dose'][3], dfa['seconda_dose'][4], dfa['seconda_dose'][5],
                               dfa['seconda_dose'][6], int(dfa['seconda_dose'][7]+dfa['seconda_dose'][8])],
                            y=['12-19', '20-29', '30-39', '40-49', '50-59', '60-69', '70-79', '80+'],
                            orientation='h',
                            marker_color='#E83A8E',
                            name='Vaccinati'
                            ),
                     go.Bar(x=[int(tot_dfe.loc[tot_dfe.index[0], 'totale_popolazione']) - int(dfa['prima_dose'][0]),
                               int(tot_dfe.loc[tot_dfe.index[1], 'totale_popolazione']) - int(dfa['prima_dose'][1]),
                               int(tot_dfe.loc[tot_dfe.index[2], 'totale_popolazione']) - int(dfa['prima_dose'][2]),
                               int(tot_dfe.loc[tot_dfe.index[3], 'totale_popolazione']) - int(dfa['prima_dose'][3]),
                               int(tot_dfe.loc[tot_dfe.index[4], 'totale_popolazione']) - int(dfa['prima_dose'][4]),
                               int(tot_dfe.loc[tot_dfe.index[5], 'totale_popolazione']) - int(dfa['prima_dose'][5]),
                               int(tot_dfe.loc[tot_dfe.index[6], 'totale_popolazione']) - int(dfa['prima_dose'][6]),
                               int(tot_dfe.loc[tot_dfe.index[7], 'totale_popolazione']) - int(dfa['prima_dose'][7])],
                            y=['12-19', '20-29', '30-39', '40-49', '50-59', '60-69', '70-79', '80+'],
                            orientation='h',
                            marker_color='#6181E8',
                            name='Non vaccinati'
                            )
                     ],
            'layout': {
                'barmode': 'stack',  # stack data
                'height': 340,  # px
                'xaxis': dict(
                    rangeslider=dict(visible=False),
                    type=''
                ),
                'legend': dict(
                    orientation="h",
                    xanchor="center",
                    x=0.5,
                    y=-0.2
                )
            },
        }
    else:
        if regione == 'Provincia Autonoma Bolzano / Bozen': reg = 'P.A. Bolzano'
        elif regione == 'Provincia Autonoma Trento': reg = 'P.A. Trento'
        elif regione == "Valle d'Aosta / Vallée d'Aoste": reg = "Valle d'Aosta"
        else: reg = regione
        ds1 = pandas.read_csv(somministrazioni)
        dfe1 = pandas.read_csv(fascia_anagrafica)
        reg_ds1 = ds1.loc[ds1['nome_area'] == regione]
        dfa1 = reg_ds1.copy().groupby('fascia_anagrafica').agg({'prima_dose': 'sum', 'seconda_dose': 'sum'}).reset_index()
        reg_dfe1 = dfe1.loc[dfe1['nome_area'] == reg]
        figure_age = {
            'data': [go.Bar(x=[int(dfa1['prima_dose'][0])-int(dfa1['seconda_dose'][0]), int(dfa1['prima_dose'][1])-int(dfa1['seconda_dose'][1]),
                               int(dfa1['prima_dose'][2])-int(dfa1['seconda_dose'][2]), int(dfa1['prima_dose'][3])-int(dfa1['seconda_dose'][3]),
                               int(dfa1['prima_dose'][4])-int(dfa1['seconda_dose'][4]), int(dfa1['prima_dose'][5])-int(dfa1['seconda_dose'][5]),
                               int(dfa1['prima_dose'][6])-int(dfa1['seconda_dose'][6]),
                               int(int(dfa1['prima_dose'][7])-int(dfa1['seconda_dose'][7])) + int(int(dfa1['prima_dose'][8])-int(dfa1['seconda_dose'][8]))],
                            y=['12-19', '20-29', '30-39', '40-49', '50-59', '60-69', '70-79', '80+'],
                            orientation='h',
                            marker_color='#F5C05F',
                            name='Prima Dose'
                            ),
                     go.Bar(x=[dfa1['seconda_dose'][0], dfa1['seconda_dose'][1], dfa1['seconda_dose'][2],
                               dfa1['seconda_dose'][3], dfa1['seconda_dose'][4], dfa1['seconda_dose'][5],
                               dfa1['seconda_dose'][6], int(int(dfa1['seconda_dose'][7]) + int(dfa1['seconda_dose'][8]))],
                            y=['12-19', '20-29', '30-39', '40-49', '50-59', '60-69', '70-79', '80+'],
                            orientation='h',
                            marker_color='#E83A8E',
                            name='Vaccinati'
                            ),
                     go.Bar(x=[int(reg_dfe1.loc[reg_dfe1.index[0], 'totale_popolazione']) - int(dfa1['prima_dose'][0]),
                               int(reg_dfe1.loc[reg_dfe1.index[1], 'totale_popolazione']) - int(dfa1['prima_dose'][1]),
                               int(reg_dfe1.loc[reg_dfe1.index[2], 'totale_popolazione']) - int(dfa1['prima_dose'][2]),
                               int(reg_dfe1.loc[reg_dfe1.index[3], 'totale_popolazione']) - int(dfa1['prima_dose'][3]),
                               int(reg_dfe1.loc[reg_dfe1.index[4], 'totale_popolazione']) - int(dfa1['prima_dose'][4]),
                               int(reg_dfe1.loc[reg_dfe1.index[5], 'totale_popolazione']) - int(dfa1['prima_dose'][5]),
                               int(reg_dfe1.loc[reg_dfe1.index[6], 'totale_popolazione']) - int(dfa1['prima_dose'][6]),
                               int(reg_dfe1.loc[reg_dfe1.index[7], 'totale_popolazione']) - int(int(dfa1['prima_dose'][7]) + int(dfa1['prima_dose'][8]))],
                            y=['12-19', '20-29', '30-39', '40-49', '50-59', '60-69', '70-79', '80+'],
                            orientation='h',
                            marker_color='#6181E8',
                            name='Non vaccinati'
                            )
                     ],
            'layout': {
                'barmode': 'stack',  # stack data
                'height': 340,  # px
                'xaxis': dict(
                    rangeslider=dict(visible=False),
                    type=''
                ),
                'legend': dict(
                    orientation="h",
                    xanchor="center",
                    x=0.5,
                    y=-0.2
                )
            },
        }
    return html.Div([
        dcc.Graph(
            figure=figure_age,
            config=chart_config
        )
    ], className='bar')

# forecast
def previsione():
    global month_last_day_vaccine
    date_format = "%Y-%m-%d"  # date format
    ora = datetime.strptime(str(today), date_format)

    # best day
    l = len(ds_dosi['data_somministrazione'])  # total vaccine day
    best_day = (60360000 - int(tot_prima)) / int(max(ds_dosi['prima_dose']))
    best_last_day = str(ora + timedelta(days=best_day))[:10]
    # 80%
    best_day_80 = (48288000 - int(tot_prima)) / int(max(ds_dosi['prima_dose']))
    best_last_day_80 = str(ora + timedelta(days=best_day_80))[:10]

    # month
    month_prima = ds_dosi.loc[ds_dosi['data_somministrazione'].between(str(ora-relativedelta(months=1))[:10], str(ora)[:10]), ['prima_dose']].sum()
    month_day_passati = (ora - (ora-relativedelta(months=1))).days
    month_day = ((60360000 - int(tot_prima)) / int(month_prima)) * month_day_passati
    month_last_day = str(ora + timedelta(days=month_day))[:10]
    # 80%
    month_day_80 = ((48288000 - int(tot_prima)) / int(month_prima)) * month_day_passati
    #month_day_80 = (48288000 / int(month_prima)) * month_day_passati
    month_last_day_80 = str(ora + timedelta(days=month_day_80))[:10]
    # 70%
    month_day_70 = ((42252000 - int(tot_prima)) / int(month_prima)) * month_day_passati
    #month_day_70 = (42252000 / int(month_prima)) * month_day_passati
    month_last_day_70 = str(ora + timedelta(days=month_day_70))[:10]
    # 60%
    month_day_60 = ((36216000 - int(tot_prima)) / int(month_prima)) * month_day_passati
    #month_day_60 = (36216000 / int(month_prima)) * month_day_passati
    month_last_day_60 = str(ora + timedelta(days=month_day_60))[:10]

    month_last_day_vaccine = month_last_day_70  # last day 70% vaccine

    return html.Div(  # main div
        dbc.Container([
            dbc.Row(
                dbc.Col(
                    dcc.Graph(
                        figure={
                            'data': [
                                {'x': ds_dosi['data_somministrazione'], 'y': (ds_dosi['prima_dose'].cumsum())/60360000, 'type': 'bar', 'name': 'Incremento Prime Dosi'},
                                go.Scatter(x=[ds_dosi['data_somministrazione'][0], '2021-10-30'],
                                           y=[0, 1],
                                           mode='lines',
                                           name='Previsione del Governo',
                                           line=go.scatter.Line(color="#FA5541")),
                                go.Scatter(x=[ds_dosi['data_somministrazione'][l-1], month_last_day_60, month_last_day_70, month_last_day_80, month_last_day],
                                           y=[int(tot_prima)/60360000, 0.6, 0.7, 0.8, 1],
                                           type='scatter',
                                           name='Previsione Mensile',
                                           line=go.scatter.Line(color="#FA924E")),
                                go.Scatter(x=[ds_dosi['data_somministrazione'][l-1], best_last_day_80, best_last_day],
                                           y=[int(tot_prima)/60360000, 0.8, 1],
                                           type='scatter',
                                           name='Previsione Migliore*',
                                           line=go.scatter.Line(color="#FAC35A"))
                            ],
                            'layout': {
                                'xaxis': dict(
                                    rangeslider=dict(visible=False),
                                    type='date'
                                ),
                                'yaxis': dict(
                                    tickformat=',.0%',  # percentage on y axis
                                    range=[0, 1]
                                ),
                                'legend': dict(
                                    orientation="h",
                                    xanchor="center",
                                    x=0.5,
                                    y=-0.2
                                )
                            }
                        },
                        config=chart_config
                    )
                )
            )
        ])
    )

# dropdown
def get_dropdown_data2():
    selections = []
    for reg in regions:
        selections.append(dict(label=reg, value=reg))
    return selections

def dropdown_velocity_dosi_graph():
    return html.Div([
        html.Div([
            dbc.Container([
                dbc.Row([
                    dbc.Col(
                        dcc.Dropdown(id='dropdown_velocity_dosi_graph', multi=True,
                                     options=get_dropdown_data2(), clearable=False, searchable=False,
                                     persistence=True, persistence_type='session', value='Lombardia'
                                     ), style={'margin-left': 'auto', 'margin-right': 'auto'}, width=12, lg=5,
                        className='mt-2')
                ])
            ])
        ])
    ])

# effect contagi
@app.callback(
    Output('velocity_dosi_graph', 'children'),
    [Input('dropdown_velocity_dosi_graph', 'value')])
def velocity_dosi_graph(regione):
    ds1 = pandas.read_csv(somministrazioni)
    data = ['']
    traces = ['']
    if type(regione) == str:
        regione = [regione]

    for reg in regione:
        ds2 = ds1[ds1['nome_area'] == reg]
        ds_dosi_velocity = ds2.groupby('data_somministrazione').agg({'prima_dose': 'sum', 'nome_area': 'last'}).reset_index()
        data.append(ds_dosi_velocity)
    data.pop(0)

    for dati in data:
        traces.append(go.Scatter({'x': dati['data_somministrazione'], 'y': dati['prima_dose'], 'mode': 'lines',
                                  'name': f"{dati['nome_area'].iloc[0]}"}))
    traces.pop(0)

    return html.Div([
        dbc.Container([
            dbc.Row(
                dbc.Col(
                    dcc.Graph(
                        figure={
                            'data': traces,
                            'layout': {
                                'xaxis': dict(
                                    rangeselector=dict(buttons=slider_button),
                                    rangeslider=dict(visible=False),
                                    type='date'
                                ),
                                'legend': dict(
                                    orientation="h",
                                    xanchor="center",
                                    x=0.5,
                                    y=-0.2
                                )
                            }
                        },
                        config=chart_config
                    )
                )
            )
        ])
    ], className='container-1')

# dropdown select
def dropdown_effetti_decessi_contagi_graph():
    return html.Div([
        html.Div([
            dbc.Container([
                dbc.Row([
                    dbc.Col(
                        dcc.Dropdown(id='dropdown_effetti_decessi_contagi_graph',
                                     options=get_dropdown_data(), clearable=False, searchable=False,
                                     persistence=True, persistence_type='session', value='Dato Nazionale'
                                     ), style={'margin-left': 'auto', 'margin-right': 'auto'}, width=12, lg=5,
                        className='mt-2')
                ])
            ])
        ])
    ])

# effect contagi
@app.callback(
    Output('effetti_contagi_graph', 'children'),
    [Input('dropdown_effetti_decessi_contagi_graph', 'value')])
def effetti_contagi_graph(regione):
    if regione == 'Dato Nazionale':
        dec = ddc
        dec['nuovi_positivi_avg'] = ddc['nuovi_positivi'].rolling(30).mean()
    else:
        # edit regions
        if regione == 'Friuli-Venezia Giulia': regione = 'Friuli Venezia Giulia'
        elif regione == 'Provincia Autonoma Bolzano / Bozen': regione = 'P.A. Bolzano'
        elif regione == 'Provincia Autonoma Trento': regione = 'P.A. Trento'
        elif regione == "Valle d'Aosta / Vallée d'Aoste": regione = "Valle d'Aosta"
        ddcr = pandas.read_csv(decessi_contagi_regioni)
        reg_ddcr = ddcr.loc[ddcr['denominazione_regione'] == regione]
        dec = reg_ddcr.copy()
        dec['nuovi_positivi_avg'] = dec['nuovi_positivi'].rolling(30).mean()

    return html.Div([
        dbc.Container([
            dbc.Row(
                dbc.Col(
                    dcc.Graph(
                        figure={
                            'data': [
                                {'x': dec['data'], 'y': dec['nuovi_positivi'], 'type': 'bar', 'name': 'Nuovi Positivi',
                                 'marker': dict(color='#D9615D')},
                                # avg 30 day
                                {'x': dec['data'], 'y': dec['nuovi_positivi_avg'], 'type': 'scatter',
                                 'name': 'Media 30g',
                                 'marker': dict(color='#FF726E')},
                                # line start vaccine
                                go.Scatter(x=['2020-12-27', '2020-12-27'],
                                           y=[0, max(dec['nuovi_positivi'])],
                                           mode='lines',
                                           name='Inizio Vaccini',
                                           hoverinfo='none',
                                           line=go.scatter.Line(color="#4F4747"))
                            ],
                            'layout': {
                                'xaxis': dict(
                                    rangeselector=dict(buttons=slider_button),
                                    rangeslider=dict(visible=False),
                                    type='date'
                                ),
                                'legend': dict(
                                    orientation="h",
                                    xanchor="center",
                                    x=0.5,
                                    y=-0.2
                                )
                            }
                        },
                        config=chart_config
                    )
                )
            )
        ])
    ], className='container-2')

# effect contagi
@app.callback(
    Output('effetti_decessi_graph', 'children'),
    [Input('dropdown_effetti_decessi_contagi_graph', 'value')])
def effetti_decessi_graph(regione):
    if regione == 'Dato Nazionale':
        ded = ddc
        ded['nuovi_decessi'] = ded.deceduti.diff().fillna(ded.deceduti)
        ded['nuovi_decessi'].iloc[121] = 31  # error -31
        # avg
        ded['nuovi_decessi_avg'] = ded['nuovi_decessi'].rolling(30).mean()
    else:
        # edit regions
        if regione == 'Friuli-Venezia Giulia': regione = 'Friuli Venezia Giulia'
        elif regione == 'Provincia Autonoma Bolzano / Bozen': regione = 'P.A. Bolzano'
        elif regione == 'Provincia Autonoma Trento': regione = 'P.A. Trento'
        elif regione == "Valle d'Aosta / Vallée d'Aoste": regione = "Valle d'Aosta"
        ddcr = pandas.read_csv(decessi_contagi_regioni)
        reg_ddcr = ddcr.loc[ddcr['denominazione_regione'] == regione]
        ded = reg_ddcr.copy()
        ded['nuovi_decessi'] = ded.deceduti.diff().fillna(ded.deceduti)
        ded['nuovi_decessi_avg'] = ded['nuovi_decessi'].rolling(30).mean()

    return html.Div([
        dbc.Container([
            dbc.Row(
                dbc.Col(
                    dcc.Graph(
                        figure={
                            'data': [
                                {'x': ded['data'], 'y': ded['nuovi_decessi'], 'type': 'bar', 'name': 'Decessi',
                                 'marker': dict(color='#756B6B')},
                                # avg 30 day
                                {'x': ded['data'], 'y': ded['nuovi_decessi_avg'], 'type': 'scatter', 'name': 'Media 30g',
                                 'marker': dict(color='#C2B0B0')},
                                # line start vaccine
                                go.Scatter(x=['2020-12-27', '2020-12-27'],
                                           y=[0, max(ded['nuovi_decessi'])],
                                           mode='lines',
                                           name='Inizio Vaccini',
                                           hoverinfo='none',
                                           line=go.scatter.Line(color="#1F1C1C"))
                            ],
                            'layout': {
                                'xaxis': dict(
                                    rangeselector=dict(buttons=slider_button),
                                    rangeslider=dict(visible=False),
                                    type='date'
                                ),
                                'legend': dict(
                                    orientation="h",
                                    xanchor="center",
                                    x=0.5,
                                    y=-0.2
                                )
                            }
                        },
                        config=chart_config
                    )
                )
            )
        ])
    ], className='container-2')

# effect contagi
def riduzione_graph():
    ds1 = pandas.read_csv(somministrazioni)
    ddcr = pandas.read_csv(decessi_contagi_regioni)
    date_format = "%Y-%m-%d"  # date format
    ora = datetime.strptime(str(today), date_format)
    traces = ['']

    for reg in regions:
        # contagi
        if reg == 'Friuli-Venezia Giulia': reg1 = 'Friuli Venezia Giulia'
        elif reg == 'Provincia Autonoma Bolzano / Bozen': reg1 = 'P.A. Bolzano'
        elif reg == 'Provincia Autonoma Trento': reg1 = 'P.A. Trento'
        elif reg == "Valle d'Aosta / Vallée d'Aoste": reg1 = "Valle d'Aosta"
        else: reg1 = reg
        # population
        if reg1 == 'Abruzzo': popolazione = 1312000
        elif reg1 == 'Basilicata': popolazione = 562869
        elif reg1 == 'Calabria': popolazione = 1947000
        elif reg1 == 'Campania': popolazione = 5802000
        elif reg1 == 'Emilia-Romagna': popolazione = 4459000
        elif reg1 == 'Friuli Venezia Giulia': popolazione = 1215000
        elif reg1 == 'Lazio': popolazione = 5879000
        elif reg1 == 'Liguria': popolazione = 1551000
        elif reg1 == 'Lombardia': popolazione = 10060000
        elif reg1 == 'Marche': popolazione = 1525000
        elif reg1 == 'Molise': popolazione = 305617
        elif reg1 == 'P.A. Bolzano': popolazione = 520891
        elif reg1 == 'P.A. Trento': popolazione = 538223
        elif reg1 == 'Piemonte': popolazione = 4356000
        elif reg1 == 'Puglia': popolazione = 4029000
        elif reg1 == 'Sardegna': popolazione = 1640000
        elif reg1 == 'Sicilia': popolazione = 5000000
        elif reg1 == 'Toscana': popolazione = 3730000
        elif reg1 == 'Umbria': popolazione = 882015
        elif reg1 == "Valle d'Aosta": popolazione = 125666
        elif reg1 == 'Veneto': popolazione = 4906000
        # data contagi
        ddcr2 = ddcr.loc[ddcr['denominazione_regione'] == reg1]
        ddcr_contagi = ddcr2.loc[ddcr2['data'].between(str(ora-timedelta(days=7))[:10], str(ora)[:10]), ['nuovi_positivi']].sum()
        positive = round((int(ddcr_contagi)*100000)/popolazione, 2)
        # doses
        ds2 = ds1[ds1['nome_area'] == reg]
        ds_dosi_velocity = ds2.groupby('data_somministrazione').agg({'prima_dose': 'sum', 'nome_area': 'last'}).reset_index()
        doses = ds_dosi_velocity.loc[ds_dosi_velocity['data_somministrazione'].between('2020-12-27', str(today)), ['prima_dose']].sum()
        doses_percent = round((int(doses) / popolazione) * 100, 2)
        # traces
        traces.append(go.Scatter({'x': [float(positive)], 'y': [float(doses_percent)], 'mode': 'markers+text', 'marker': dict(color='crimson', size=12), 'text': f"{reg1}", 'textfont':dict(color='#B01B3E'), 'textposition': 'middle right', 'name': f"{reg1}"}))
    traces.pop(0)

    return html.Div([
        dbc.Container([
            dbc.Row(
                dbc.Col(
                    dcc.Graph(
                        figure={
                            'data': traces,
                            'layout': {
                                'xaxis': dict(
                                    rangeslider=dict(visible=False),
                                ),
                                'yaxis': {'title': 'Percentuale di Vaccinati'},
                                'xaxis': {'title': 'Nuovi positivi'},
                                'showlegend': False,
                            }
                        },
                        config=chart_config
                    )
                )
            )
        ])
    ], className='container-1')

def layout():
    refresh_data()
    return html.Div([
        # style
        html.Link(rel="stylesheet", media="screen and (min-width: 900px)", href="./assets/big.css"),
        html.Link(rel="stylesheet", media="screen and (max-width: 900px)", href="./assets/small.css"),
        # vaccine total
        html.Div([html.Br(), html.Br(), html.Center(html.H1('Vaccini')), html.Br(), html.Br()]),
        html.Div([vaccine_update()]),
        html.Div([vaccine_update_bar()]),  # orizzonatl bar
        # text
        html.Div(html.Center(html.I([html.Br(), "L'obiettivo della campagna di vaccinazione della popolazione è prevenire le morti da COVID-19 e raggiungere al più presto ", html.B("l'immunità di gregge"), " per il SARS-CoV2", html.Br(), "La campagna è partita il ", html.B("27 dicembre"), ", vista l'approvazione da parte dell'EMA del primo vaccino anti COVID-19.", html.Br(), "Dopo una fase iniziale, che dovrà essere limitata, per il numero di dosi consegnate, essa si svilupperà in continuo crescendo.", html.Br(), "I vaccini saranno offerti a ", html.B("tutta la popolazione"), ", secondo un ordine di ", html.B("priorità"), ", che tiene conto del rischio di ", html.B("malattia"), ", dei tipi di ", html.B("vaccino"), " e della loro ", html.B("disponibilità")], style={'font-size': 'large'}))),
        # daily data
        html.Div([html.Br(), html.Br(), html.Br(), html.Center(html.H1('Dati del Giorno')), html.Center(html.I('dati aggionati del '+str(last_update), style={'font-size': '14px'})), html.Br()]),
        html.Div([dropdown_vaccine_daily(), html.Br()]),  # dropdown
        html.Div(id='vaccine_daily'),
        # vaccine and doses
        html.Div([html.Br(), html.Br(), html.Center(html.H2('Vaccini & Dosi'))]),
        html.Div([html.Div(id='vaccine_graph'), html.Div(id='dosi_graph')], className='container-1'),
        # image
        html.Div(html.Center([html.Div([html.Img(src='./assets/ddoses.png', width="45", style={'vertical-align': 'bottom'}), html.B(' 2'), ' Dosi: ', html.I('Pfizer, Moderna e AstraZeneca', style={'font-size': '14px'})], className='container-2'), html.Div([html.Img(src='./assets/doses.png', width="30", style={'vertical-align': 'bottom'}), html.B(' 1'), ' Dose:', html.I(' Janssen', style={'font-size': '14px'})], className='container-2'),
                              html.Div([html.Br(), html.Br(), html.Br(), html.H2('Vaccini per fascia di età'), html.I('I dati sono calcolati sulle somministrazioni delle prime dosi', style={'font-size': '14px'})], className='container-1')], className='container-1')),
        html.Div([dropdown_vaccine_age_bar()]),
        html.Div(id='vaccine_age_bar'),
        html.Div([html.Div(id='category_global')], className='container-1'),
        # forecast
        html.Div([html.Br(), html.Br(), html.Br(), html.Center(html.H1('Previsioni')), html.Center(html.I('Il modello utilizza i dati giornalieri sulle somministrazioni delle prime dosi', style={'font-size': '14px'})), html.Center(html.I('*Media basata sul valore massimo di prime dosi fatte in un giorno, ad ora '+str(max_prima_f), style={'font-size': '14px'}))]),
        html.Div([previsione()]),
        # text forecast
        html.Div(html.Center([html.Br(), "Nell'ultimo ", html.B("mese"), " sono state somministrate ", html.Mark([html.B(str(max_prima_f)), " prime dosi"], style={'background-color': '#F5C05F'}),
             " in ", html.B("Italia"), " di cui ", html.Mark([html.B(str(tot_janssenf)), " monodose"], style={'background-color': '#F5C05F'}), html.Br(),
             "A questo ritmo il ", html.B("70% della popolazione"), " sarà vaccinata entro il ", html.Mark([str(month_last_day_vaccine)], style={'background-color': '#F5C05F'})])),
        # velocity
        html.Div([html.Br(), html.Br(), html.Br(), html.Center(html.H2('Velocità vaccinazioni')), html.Center(html.I('I dati sono calcolati sulle somministrazioni delle prime dosi', style={'font-size': '14px'}))]),
        html.Div([dropdown_velocity_dosi_graph()]),
        html.Div([html.Div(id='velocity_dosi_graph')], className='container-1'),
        # effect
        html.Div([html.Br(), html.Br(), html.Br(), html.Center(html.H2('Effetti dei Vaccini nel Tempo')), html.Br()]),
        html.Div([dropdown_effetti_decessi_contagi_graph(), html.Br()]),
        html.Div([html.Div(id='effetti_contagi_graph'), html.Div(id='effetti_decessi_graph')], className='container-1'),
        # text effect
        html.Div(html.Center([html.Div([html.Br(), "Contagi ", html.B("ultimo mese"), " in Italia: ", html.Mark([html.B("%s" %("+" if int(percent_mese) > 100 else "-")+str(float(percent_mese))+'%')], style={'background-color': '#F5C05F'})], className='container-2'),
                              html.Div([html.Br(), "Decessi ", html.B("ultimo mese"), " in Italia: ", html.Mark([html.B("%s" %("+" if int(percent_mese_death) > 100 else "-")+str(float(percent_mese_death))+'%')], style={'background-color': '#F5C05F'})], className='container-2'),
                              html.Div([html.Br(), html.Br(), html.Br(), html.H4('Quanto le vaccinazioni stanno contribuendo veramente alla riduzione dei contagi?'), html.I("I dati sono calcolati sulla percentuale di popolazione vaccinata e sull'incidenza dei contagi, nell'ultima settimana, per 100.000 abitanti", style={'font-size': '14px'})], className='container-1')], className='container-1')),
        # text riduzione
        html.Div([html.Br(), riduzione_graph()]),
    ])

app.layout = layout

if __name__ == '__main__':
    app.run_server(host='0.0.0.0', port=8050, debug=False)


from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import (
    scoped_session,
    sessionmaker,
    relationship,
    backref
    )
from zope.sqlalchemy import ZopeTransactionExtension

pbbDBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension(),
                              autocommit=False,
                              autoflush=False,))
pbbBase = declarative_base()
from ...tools import get_settings
settings = get_settings()
pbb_schema = settings and 'schema.pbb' in settings and settings['schema.pbb'] or 'pbb'

PBB_ARGS = {'extend_existing':True,
        'schema': pbb_schema}


# -*- encoding: utf-8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import asyncio
import dataclasses
import json

import daiquiri
import redis

from mergify_engine import check_api
from mergify_engine import context
from mergify_engine import exceptions
from mergify_engine import subscription
from mergify_engine import utils
from mergify_engine.actions.merge import helpers
from mergify_engine.clients import github

LOG = daiquiri.getLogger(__name__)

@dataclasses.dataclass
class Queue:
    redis: redis.Redis
    installation_id: int
    owner: str
    repo: str
    ref: str

    @property
    def log(self):
        return daiquiri.getLogger(
            __name__, gh_owner=self.owner, gh_repo=self.repo, gh_branch=self.ref
        )

    @classmethod
    def from_queue_name(cls, redis, name):
        _, installation_id, owner, repo, branch = name.split("~")
        return cls(redis, int(installation_id), owner, repo, branch)

    @classmethod
    def from_context(cls, ctxt):
        return cls(
            utils.get_redis_for_cache(),
            ctxt.client.auth.installation["id"],
            ctxt.pull["base"]["repo"]["owner"]["login"],
            ctxt.pull["base"]["repo"]["name"],
            ctxt.pull["base"]["ref"],
        )

    @property
    def _cache_key(self):
        return f"strict-merge-queues~{self.installation_id}~{self.owner}~{self.repo}~{self.ref}"

    def _config_cache_key(self, pull_number):
        return f"strict-merge-config~{self.installation_id}~{self.owner}~{self.repo}~{pull_number}"

    def get_config(self, pull_number: int) -> dict:
        """Return merge config for a pull request.

        :param pull_number: The pull request number.
        """
        config = self.redis.get(self._config_cache_key(pull_number))
        if config is None:
            # FIXME(sileht): We should never ever pass here in theory, but
            # Currently we can have race condition like:
            # * smart queue coro: get next PR
            # * engine coro: get merge event
            # * engine coro: cleanup queue with 3 redis cmds without transaction
            # * smart queue coro: get merge config (get_config()), and got None.
            # That's not a huge deal
            # TODO(sileht): Everything about queue should be done in redis transaction
            # e.g.: add/update/get/del of a pull in queue
            return {
                "strict_method": "merge",
                "priority": 2000,
                "effective_priority": 2000,
                "bot_account": None,
                "update_bot_account": None,
            }
        config = json.loads(config)
        # TODO(sileht): for compatibility purpose, we can drop that in a couple of week
        config.setdefault("effective_priority", config["priority"])
        config.setdefault("bot_account", None)
        config.setdefault("update_bot_account", None)
        return config

    def _add_pull(self, pull_number, priority, update=False):
        """Add a pull without setting its method.

        :param update: If update is True, don't create PR if it's not there.
        """
        score = utils.utcnow().timestamp() / priority
        if update:
            flags = dict(xx=True)
        else:
            flags = dict(nx=True)
        self.redis.zadd(self._cache_key, {pull_number: score}, **flags)

    def add_pull(self, ctxt, config):
        config = config.copy()
        config["effective_priority"] = config["priority"]

        if not ctxt.subscription.has_feature(subscription.Features.PRIORITY_QUEUES):
            config["effective_priority"] = helpers.PriorityAliases.medium.value

        self.redis.set(
            self._config_cache_key(ctxt.pull["number"]),
            json.dumps(config),
        )
        self._add_pull(ctxt.pull["number"], config["effective_priority"])
        self.log.info(
            "pull request added to merge queue",
            gh_pull=ctxt.pull["number"],
            config=config,
        )

    def _remove_pull(self, pull_number):
        """Remove the pull request from the queue, leaving the config."""
        self.redis.zrem(self._cache_key, pull_number)

    def remove_pull(self, pull_number):
        self._remove_pull(pull_number)
        self.redis.delete(self._config_cache_key(pull_number))
        self.log.info("pull request removed from merge queue", gh_pull=pull_number)

    def _move_pull_at_end(self, pull_number):  # pragma: no cover
        priority = self.get_config(pull_number)["effective_priority"]
        self._add_pull(pull_number, priority=priority, update=True)
        self.log.info(
            "pull request moved at the end of the merge queue", gh_pull=pull_number
        )

    def get_queue(self, ref):
        """Get a queue for another ref of this repository."""
        return self.__class__(
            self.redis,
            self.installation_id,
            self.owner,
            self.repo,
            ref,
        )

    def move_pull_to_new_base_branch(self, pull_number, new_queue):
        self._remove_pull(pull_number)
        priority = self.get_config(pull_number)["effective_priority"]
        new_queue._add_pull(pull_number, priority)
        self.log.info(
            "pull request moved from this queue to %s",
            new_queue,
            gh_pull=pull_number,
        )

    def is_first_pull(self, ctxt):
        pull_requests = self.get_pulls()
        if not pull_requests:
            ctxt.log.error("is_first_pull() called on empty queues")
            return True
        return pull_requests[0] == ctxt.pull["number"]

    def get_pulls(self):
        return [
            int(pull)
            for pull in self.redis.zrangebyscore(self._cache_key, "-inf", "+inf")
        ]

    def delete(self):
        self.redis.delete(self._cache_key)

    def handle_first_pull_in_queue(self, ctxt):
        old_checks = [
            c for c in ctxt.pull_engine_check_runs if c["name"].endswith(" (merge)")
        ]

        result = helpers.merge_report(ctxt, True)
        if result:
            ctxt.log.info(
                "pull request closed in the meantime",
                result=result,
            )
            self.remove_pull(ctxt.pull["number"])
        else:
            ctxt.log.info("updating base branch of pull request")
            config = self.get_config(ctxt.pull["number"])
            result = helpers.update_pull_base_branch(
                ctxt,
                config["strict_method"],
                config["update_bot_account"] or config["bot_account"],
            )

            if ctxt.pull["state"] == "closed":
                ctxt.log.info(
                    "pull request closed in the meantime",
                    result=result,
                )
                self.remove_pull(ctxt.pull["number"])
            elif result.conclusion == check_api.Conclusion.FAILURE:
                ctxt.log.info(
                    "base branch update failed",
                    result=result,
                )
                self._move_pull_at_end(ctxt.pull["number"])

        for c in old_checks:
            check_api.set_check_run(ctxt, c["name"], result)

    @classmethod
    def process_queues(cls):
        with utils.get_redis_for_cache() as redis:
            LOG.info("smart strict workflow loop start")
            for queue_name in redis.keys("strict-merge-queues~*"):
                queue = cls.from_queue_name(redis, queue_name)
                try:
                    queue.process()
                except exceptions.MergifyNotInstalled:
                    queue.delete()
                except Exception:
                    queue.log.error("Fail to process merge queue", exc_info=True)
            LOG.info("smart strict workflow loop end")

    def process(self):
        pull_numbers = self.get_pulls()

        self.log.info("%d pulls queued", len(pull_numbers), queue=list(pull_numbers))

        if not pull_numbers:
            return

        pull_number = pull_numbers[0]

        with github.get_client(self.owner) as client:
            ctxt = None
            try:
                sub = asyncio.run(
                    subscription.Subscription.get_subscription(client.auth.owner_id)
                )
                data = client.item(
                    f"/repos/{self.owner}/{self.repo}/pulls/{pull_number}"
                )

                ctxt = context.Context(client, data, sub)
                if ctxt.pull["base"]["ref"] != self.ref:
                    ctxt.log.info(
                        "pull request base branch have changed",
                        old_branch=self.ref,
                        new_branch=ctxt.pull["base"]["ref"],
                    )
                    self.move_pull_to_new_base_branch(
                        ctxt.pull["number"],
                        self.get_queue(ctxt.pull["base"]["ref"]),
                    )
                elif ctxt.pull["state"] == "closed" or ctxt.is_behind:
                    # NOTE(sileht): Pick up this pull request and rebase it again
                    # or update its status and remove it from the queue
                    ctxt.log.info(
                        "pull request needs to be updated again or has been closed",
                    )
                    self.handle_first_pull_in_queue(ctxt)
                else:
                    # NOTE(sileht): Pull request has not been merged or cancelled
                    # yet wait next loop
                    ctxt.log.info("pull request checks are still in progress")

            except Exception as exc:  # pragma: no cover
                log = self.log if ctxt is None else ctxt.log

                if exceptions.should_be_ignored(exc):
                    log.info(
                        "Fail to process merge queue, remove the pull request from the queue",
                        exc_info=True,
                    )
                    self.remove_pull(ctxt.pull["number"])

                elif exceptions.need_retry(exc):
                    log.info("Fail to process merge queue, need retry", exc_info=True)
                    if isinstance(exc, exceptions.MergeableStateUnknown):
                        # NOTE(sileht): We need GitHub to recompute the state here (by
                        # merging something else for example), so move it to the end
                        self._move_pull_at_end(pull_number)

                else:
                    log.error("Fail to process merge queue", exc_info=True)
                    self._move_pull_at_end(pull_number)


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

import cv2
import numpy as np

def detect_finish(frame):
    # Crop the image
    crop_img = frame

    # Convert to grayscale
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    # Gaussian blur
    blur = cv2.GaussianBlur(hsv,(5,5),0)

    lower_blue = np.array([60, 40, 40])
    upper_blue = np.array([150, 255, 255])
    mask = cv2.inRange(hsv, lower_blue, upper_blue)

    # Find the contours of the frame
    contours,hierarchy = cv2.findContours(mask.copy(), 1, cv2.CHAIN_APPROX_NONE)

    # Find the biggest contour (if detected)
    if len(contours) > 0:
        return True
    else:
        return False


import collections
import threading

class ThreadedRWIO(object):
  """
  A file-like object that can be written from one thread and read from
  another. Allows piping data using #write() to another thread that uses
  #read() on the same file.
  """

  def __init__(self, type=bytes):
    assert type in (bytes, str)
    self._type = type
    self._deque = collections.deque()
    self._lock = threading.Lock()
    self._cond = threading.Condition(self._lock)
    self._write_closed = False
    self._read_pos = 0
    self._write_pos = 0

  def read(self, num_bytes=None):
    result = []
    bytes_read = 0
    with self._cond:
      while num_bytes is None or bytes_read < num_bytes:
        if not self._deque and self._write_closed:
          break
        elif not self._deque:
          self._cond.wait()  # wait for more data
        else:
          data = self._deque.popleft()
          if num_bytes and len(data) > num_bytes - bytes_read:
            delta = num_bytes - bytes_read
            data, remainder = data[:delta], data[delta:]
            self._deque.appendleft(remainder)
          result.append(data)
          bytes_read += len(data)
    data = self._type().join(result)
    self._read_pos += len(data)
    return data

  def write(self, data):
    if not isinstance(data, self._type):
      raise TypeError('expected {}, got {}'.format(self._type.__name__, type(data).__name__))
    with self._cond:
      if self._write_closed:
        raise RuntimeError('writing is closed')
      self._deque.append(data)
      self._cond.notify()
    self._write_pos += len(data)
    return len(data)

  def seekable(self):
    return False

  def readable(self):
    return True

  def writable(self):
    return True

  def tell(self):
    return self._read_pos

  def closed(self):
    return False

  def close(self):
    with self._cond:
      self._write_closed = True
      self._cond.notify_all()


# -*- coding: cp950 -*-
import io
import numpy as np
result = 'utf8-ZhuYin.map'
ffresult = 'ZhuYin-utf8.map'
f = io.open(result, 'r' ,encoding = 'utf-8')
zhuyin = [u'£t',u'£u',u'£v',u'£w',u'£x',u'£y',u'£z',u'£{',u'£|',u'£}',u'£~',u'£¡',u'£¢',u'££',u'£¤',u'£¥',u'£¦',u'£§',u'£¨',u'£©',u'£ª',u'£¸',u'£¹',u'£º',u'£«',u'£¬',u'£',u'£®',u'£¯',u'£°',u'£±',u'£²',u'£³',u'£´',u'£µ',u'£¶',u'£·']
qq = []
for i in range(0,37,1):
    qqq = []
    qq.append(qqq)
while True:
    lines = f.readline()
    if not lines:
        break
    for i in range (0,37,1):
       if lines[2] == zhuyin[i]:
           qq[i].append(lines[0])
ff = io.open(ffresult, 'w' , encoding = 'utf-8')
#print len(qq[0])
for i in range(0,37,1):
    ff.write(zhuyin[i])
    ff.write(u' ')
    for j in range(0,len(qq[i]),1):
        ff.write(qq[i][j])
        ff.write(u' ')
    ff.write(u'\n')
    for k in range(0,len(qq[i]),1):
        ff.write(qq[i][k])
        ff.write(u' ')
        ff.write(qq[i][k])
        ff.write(u'\n')
ff.close()


import datetime
import itertools

import simulator.sim
from simulator import CommandLineCommon

import algorithm
protectionless = algorithm.import_algorithm("protectionless")
phantom_chen = algorithm.import_algorithm("phantom_chen")
lprouting_chen = algorithm.import_algorithm("ilprouting_chen")
adaptive_spr_notify_chen = algorithm.import_algorithm("adaptive_spr_notify_chen")

from data import results

from data.table import fake_result, comparison
from data.graph import summary, min_max_versus, dual_min_max_versus
from data.util import scalar_extractor

from data import submodule_loader

class CLI(CommandLineCommon.CLI):
    def __init__(self):
        super(CLI, self).__init__(protectionless.name)

        subparser = self._add_argument("table", self._run_table)
        subparser.add_argument("sim", choices=submodule_loader.list_available(simulator.sim), help="The simulator you wish to run with.")
        subparser.add_argument("--show", action="store_true", default=False)

        subparser = self._add_argument("graph", self._run_graph)
        subparser.add_argument("sim", choices=submodule_loader.list_available(simulator.sim), help="The simulator you wish to run with.")

        subparser = self._add_argument("graph-sf", self._run_graph_sf)
        subparser.add_argument("sim", choices=submodule_loader.list_available(simulator.sim), help="The simulator you wish to run with.")

        subparser = self._add_argument("graph-min-max", self._run_min_max_versus)
        subparser.add_argument("sim", choices=submodule_loader.list_available(simulator.sim), help="The simulator you wish to run with.")

    def _cluster_time_estimator(self, sim, args, **kwargs):
        """Estimates how long simulations are run for. Override this in algorithm
        specific CommandLine if these values are too small or too big. In general
        these have been good amounts of time to run simulations for. You might want
        to adjust the number of repeats to get the simulation time in this range."""
        size = args['network size']
        if size == 11:
            return datetime.timedelta(hours=1)
        elif size == 15:
            return datetime.timedelta(hours=2)
        elif size == 21:
            return datetime.timedelta(hours=3)
        elif size == 25:
            return datetime.timedelta(hours=4)
        else:
            raise RuntimeError("No time estimate for network sizes other than 11, 15, 21 or 25")

    def time_after_first_normal_to_safety_period(self, tafn):
        return tafn

    def _run_table(self, args):
        parameters = [
            'normal latency',
            'norm(sent,time taken)',
            'captured',
            'received ratio',
            #'attacker distance wrt src',
            #'attacker distance',
            #'failed avoid sink',
            #'failed avoid sink when captured',
        ]

        self._create_results_table(args.sim, parameters, show=args.show)

    def _run_graph(self, args):
        graph_parameters = {
            'normal latency': ('Message Latency (msec)', 'left top'),
            #'ssd': ('Sink-Source Distance (hops)', 'left top'),
            'captured': ('Capture Ratio (%)', 'left top'),
            #'sent': ('Total Messages Sent', 'left top'),
            'received ratio': ('Receive Ratio (%)', 'left bottom'),
            'norm(sent,time taken)': ('Messages Transmission (messages)', 'left top'),
            #'norm(norm(sent,time taken),network size)': ('Messages Sent per Second per Node', 'left top'),
            #'attacker distance': ('Attacker Distance From Source (Meters)', 'left top'),
            #'failed avoid sink': ('Failed to Avoid Sink (%)', 'left top'),
            #'failed avoid sink when captured': ('Failed to Avoid Sink When Captured (%)', 'left top'),
        }

        varying = [
            #(('network size', ''), ('source period', '')),
            (('network size', ''), ('sleep probability', '')),
        ]

        custom_yaxis_range_max = {
            'captured': 80,
            'received ratio': 100,
            'normal latency': 200,
            'norm(sent,time taken)': 2000
        }

        def filter_params(all_params):
            return all_params['safety factor'] != '1.3'

        yextractors = { }

        self._create_versus_graph(args.sim, graph_parameters, varying,
            custom_yaxis_range_max=custom_yaxis_range_max,
            results_filter=filter_params,
            yextractor = yextractors,
            xaxis_font = "',16'",
            yaxis_font = "',16'",
            xlabel_font = "',18'",
            ylabel_font = "',16'",
            line_width = 3,
            point_size = 1,
            nokey = True,
            generate_legend_graph = True,
            legend_font_size = 16,
        )

    def _run_graph_sf(self, args):
        graph_parameters = {
            'normal latency': ('Message Latency (msec)', 'left top'),
            #'ssd': ('Sink-Source Distance (hops)', 'left top'),
            'captured': ('Capture Ratio (%)', 'left top'),
            #'sent': ('Total Messages Sent', 'left top'),
            'received ratio': ('Receive Ratio (%)', 'left bottom'),
            'norm(sent,time taken)': ('Messages Transmission (messages)', 'left top'),
            #'norm(norm(sent,time taken),network size)': ('Messages Sent per Second per Node', 'left top'),
            #'attacker distance': ('Attacker Distance From Source (Meters)', 'left top'),
            #'failed avoid sink': ('Failed to Avoid Sink (%)', 'left top'),
            #'failed avoid sink when captured': ('Failed to Avoid Sink When Captured (%)', 'left top'),
        }

        varying = [
            #(('network size', ''), ('source period', '')),
            (('safety factor', ''), ('sleep probability', '')),
        ]

        custom_yaxis_range_max = {
            'captured': 100,
            'received ratio': 100,
            'normal latency': 200,
            'norm(sent,time taken)': 2000
        }

        yextractors = { }

        self._create_versus_graph(args.sim, graph_parameters, varying,
            custom_yaxis_range_max=custom_yaxis_range_max,
            yextractor = yextractors,
            xaxis_font = "',16'",
            yaxis_font = "',16'",
            xlabel_font = "',18'",
            ylabel_font = "',16'",
            line_width = 3,
            point_size = 1,
            nokey = True,
            generate_legend_graph = True,
            legend_font_size = 16,
        )

    def _run_min_max_versus(self, args):
        graph_parameters = {
            'normal latency': ('Message Latency (msec)', 'left top'),
            'captured': ('Capture Ratio (%)', 'left top'),
            'received ratio': ('Receive Ratio (%)', 'left bottom'),
            'norm(sent,time taken)': ('Messages Transmission (messages)', 'left top'),
        }

        custom_yaxis_range_max = {
            'captured': 100,
            'received ratio': 100,
            'normal latency': 3000,
            'norm(sent,time taken)': 2000
        }

        key_equivalence = {
            "attacker model": {"SeqNosReactiveAttacker()": "SeqNosOOOReactiveAttacker()"}
        }

        varying = [
            (('safety factor', ''), ('sleep probability', '')),
        ]

        args = (
            args.sim, [phantom_chen, lprouting_chen, adaptive_spr_notify_chen], None, graph_parameters, varying
        )

        kwargs = {
            "min_label": ["Phantom - Min", "ILP - Min", "AdaptiveSPR - Min"],
            "max_label": ["Phantom - Max", "ILP - Max", "AdaptiveSPR - Max"],
            "min_max_same_label": ["Phantom", "ILP", "AdaptiveSPR"],
            "vary_label": "",
            #"comparison_label": "PW",
            #"vvalue_label_converter": self.vvalue_converter,
            "key_equivalence": key_equivalence,
            "nokey": True,
            "generate_legend_graph": True,
            "custom_yaxis_range_max": custom_yaxis_range_max,
        }

        self._create_min_max_versus_graph(*args, **kwargs)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
import django_hstore.fields

class Migration(migrations.Migration):

    dependencies = [
        ('dataportal3', '0025_auto_20160202_0005'),
    ]

    operations = [
        migrations.AddField(
            model_name='nomissearch',
            name='display_fields',
            field=django_hstore.fields.DictionaryField(null=True, blank=True),
        ),
    ]


# coding: utf-8
import cherrypy
import cherrypy
from google import google
num_page = 3
search_results = google.search("This is my query", num_page)
search_results
import json
import pprint as pp
get_ipython().magic(u'cd c:\\projects\\APKY\\PES601\\Project\\SearchAssistant\\resources\\GoogleSearchAPI\\google-api-python-client-master\\google-api-python-client-master\\samples\\customsearch')
get_ipython().magic(u'pwd ')
with open('out.json') as datfile:
    data = json.load(datfile)

get_ipython().magic(u'cd c:\\projects\\APKY\\PES601\\Project\\SearchAssistant\\searchassistant')
with open('out.json') as datfile:
    data = json.load(datfile)
with open('out2.json') as datfile:
    data = json.load(datfile)
with open('out3.json') as datfile:
    data = json.load(datfile)
with open('out2.json') as datfile:
    data = json.load(datfile)
with open('out4.json') as datfile:
    data = json.load(datfile)
with open('out4.json') as datfile:
    data = json.load(datfile)
with open('out4.json') as datfile:
    data = json.load(datfile)
get_ipython().magic(u'pwd ')
execfile('gsearchtest.py')
r = main()
r
r[0]
r.keys
r.keys()
r.items
r.items()
r.items.keys()
r['items']
r['items'].keys()
r['items'][0]
r['items'][1]
r['items'][0]
r['items'][1]
[x['title'] for x in r['items']]
get_ipython().magic(u'pinfo2 main')
execfile('gsearchtest.py')
execfile('gsearchtest.py')
r
[x['title'] for x in r['items']]
execfile('gsearchtest.py')
r = main()
r = main()
import pickle
output = open('result.pkl','wb')
pickle.dump(r, output)
output.close()
def pkl(o):
    with open('result.pkl','wb') as out:
        pickle.dump(o, out, -1)

pkl(r)
def upkl(file):
    with open(file, 'rb') as input:
        res = pickle.load(input)
    return res
rback = upkl('result.pkl')
rback
[x['title'] for x in rback['items']]
get_ipython().magic(u'hist -n')


import os,DBcall,datetime,json,collections,isbnlib
class BookManagement:
    def checkOut(self,ISBN,Borrow):
        sql = DBcall.Mysql()
        return sql.checkOut(ISBN,Borrow)

    def addBook(self,ISBN):
        sql = DBcall.Mysql()
        temp = sql.checkBook(ISBN)
        admin = open("cache/admin.txt").read()
        if temp:
            file = open('logs/bookLog/' + ISBN + '.txt', 'a')
            info = sql.addcopy(ISBN)
            file.write("\n")
            file.write(str(datetime.datetime.now())[:-7] + '_' +"Book Copy "+info +" added by " + admin)
            file.close()
            return "Book Copy "+info +" added"

        else:
            file = open('logs/bookLog/' + ISBN + '.txt', 'w')
            info = sql.addbook(ISBN)
            p, lan, ti, au, isbn, y = info
            file.write(ISBN)
            file.write("\n")
            file.write(ti)
            file.write("\n")
            file.write(au[0])
            file.write("\n")
            file.write(p)
            file.write("\n")
            file.write(lan)
            file.write("\n")
            file.write(y)
            file.write("\n")
            file.write(str(datetime.datetime.now())[:-7] + '_' + 'Book Created by ' + admin)
            file.write("\n")
            file.write(str(datetime.datetime.now())[:-7] + '_' + 'Book Copy 001 added by ' + admin)
            file.close()
            return "Book " +ti+ " add into Library"

    def returnBook(self,ISBN,Borrow):
        sql = DBcall.Mysql()
        sql.returnBook(ISBN,Borrow)

    def pickUp(self,ISBN,Borrow):
        sql = DBcall.Mysql()
        sql.pickUp(ISBN,Borrow)

    def checkOut(self,ISBN,Borrow):
        sql = DBcall.Mysql()
        sql.checkOut(ISBN,Borrow)

    def appendLog(self,path,content):
        file = open(path, 'a')
        for item in content:
            file.write("\n")
            file.write(str(datetime.datetime.now())[:-7] +'_'+item)
        file.close()

    def convertToTuple(self,dict):
        res = []
        for key,value in dict.items():
            res.append((int(value),key))
        return res

    def topBook(self,ISBN,count):
        dir = "cache/topBooks.txt"
        file = open(dir, 'r')
        data = json.load(file)
        file.close()
        if ISBN in data:
            data[ISBN] = count
        else:data[ISBN] = count
        tens = self.convertToTuple(data)
        tens = sorted(tens)
        while len(tens) > 10:
            tens.pop(0)
        dic = collections.defaultdict(int)
        for item in tens:
            dic[item[1]] = int(item[0])
        r = json.dumps(dic)
        file = open(dir,'w')
        file.write(r)
        file.close()

    def topReader(self,ID,count):
        dir = "cache/topBorrowers.txt"
        file = open(dir, 'r')
        data = json.load(file)
        file.close()
        if ID in data:
            data[ID] = count
        else:data[ID] = count
        tens = self.convertToTuple(data)
        tens = sorted(tens)
        while len(tens) > 10:
            tens.pop(0)
        dic = collections.defaultdict(int)
        for item in tens:
            dic[item[1]] = int(item[0])
        r = json.dumps(dic)
        file = open(dir,'w')
        file.write(r)
        file.close()


import os
import sys
import json
import random
from tkinter import *
import tkinter.ttk as ttk
from tkinter import messagebox

class Quiz:
    def __init__(self):
        self.prev_widget = ''
        self.quiz_numbers = []
        self.file_name = 'quiz.json'
        self.buttons_attributes = {'fg': 'white', 'activeforeground': 'white', 'cursor': 'hand2', 'relief': RIDGE}

        self.master = Tk()

        self.title_img_obj = PhotoImage(file=self.resource_path(self.resource_path('included_files\\title.png')))
        self.title_label = Label(self.master, image=self.title_img_obj, bd=0, bg='white')
        self.title_label.pack(ipadx=13)

        self.add_labelframe = LabelFrame(self.master, text='Add Q/A', bg='white')
        self.question_entry_style = ttk.Style()
        self.question_entry_style.configure('Q.TEntry', foreground='grey')
        self.question_entry = ttk.Entry(self.add_labelframe, width=40, justify='center', style='Q.TEntry')
        self.question_entry.insert(END, 'QUESTION')
        self.question_entry.pack(pady=5, ipady=3)

        self.answer_entry_style = ttk.Style()
        self.answer_entry_style.configure('A.TEntry', foreground='grey')
        self.answer_entry = ttk.Entry(self.add_labelframe, width=40, justify='center', style='A.TEntry')
        self.answer_entry.insert(END, 'ANSWER')
        self.answer_entry.pack(pady=5, ipady=3)

        self.add_button = Button(self.add_labelframe, text='ADD QUESTION', bg='red', activebackground='red', **self.buttons_attributes, command=self.add_button_command)
        self.add_button.pack(pady=5, ipady=3, ipadx=73)
        self.add_labelframe.pack(pady=10, ipadx=10)

        self.pick_labelframe = LabelFrame(self.master, text='PICK QUESTION', bg='white')
        self.pick_question_entry_style = ttk.Style()
        self.pick_question_entry_style.configure('QN.TEntry', foreground='grey')
        self.pick_question_entry = ttk.Entry(self.pick_labelframe, width=40, justify='center', style='QN.TEntry')
        self.pick_question_entry.insert(END, 'QUESTION NUMBER')
        self.pick_question_entry.pack(pady=5, ipady=3)

        self.pick_button = Button(self.pick_labelframe, text='PICK', bg='green', activebackground='green', **self.buttons_attributes, command=self.manual_pick_question)
        self.pick_button.pack(pady=5, ipady=3, ipadx=107)

        self.random_pick_button = Button(self.pick_labelframe, text='PICK RANDOM QUESTION', bg='blue', activebackground='blue', **self.buttons_attributes, command=self.random_pick_question)
        self.random_pick_button.pack(pady=5, ipady=3, ipadx=47)
        self.pick_labelframe.pack(ipadx=10)

        self.master.after(0, self.center_window)
        self.master.bind('<Control-n>', self.show_numbers)
        self.master.bind('<Control-N>', self.show_numbers)
        self.master.bind('<Button-1>', self.master_bindings)
        self.add_button.bind('<FocusIn>', self.entry_bindings)
        self.pick_button.bind('<FocusIn>', self.entry_bindings)
        self.answer_entry.bind('<FocusIn>', self.entry_bindings)
        self.add_button.bind('<Return>', self.add_button_command)
        self.question_entry.bind('<FocusIn>', self.entry_bindings)
        self.answer_entry.bind('<Return>', self.add_button_command)
        self.pick_button.bind('<Return>', self.manual_pick_question)
        self.question_entry.bind('<Return>', self.add_button_command)
        self.pick_question_entry.bind('<FocusIn>', self.entry_bindings)
        self.random_pick_button.bind('<Return>', self.manual_pick_question)
        self.pick_question_entry.bind('<Return>', self.manual_pick_question)

        self.master.config(bg='white')
        self.master.mainloop()

    def center_window(self):
        '''Setting initial position to the center of the screen'''

        self.master.withdraw()
        self.master.update()

        width, height = self.master.winfo_width(), self.master.winfo_height() + 5
        screen_width, screen_height = self.master.winfo_screenwidth() // 2, self.master.winfo_screenheight() // 2
        self.master.geometry(f'{width}x{height}+{screen_width - width // 2}+{screen_height - height // 2}')
        self.master.iconbitmap(self.resource_path('included_files\\icon.ico'))
        self.master.title('Quiz')

        self.master.deiconify()
        self.master.resizable(0, 0)

    def master_bindings(self, event=None):
        '''When user clicks anywhere outside of entry boxes and buttons'''

        widget = event.widget
        widgets = [self.question_entry, self.answer_entry, self.pick_question_entry, self.add_button, self.pick_button, self.random_pick_button]
        entries_widgets = {self.question_entry: 'QUESTION', self.answer_entry: 'ANSWER', self.pick_question_entry: 'QUESTION NUMBER'}
        entries_styles = {self.question_entry: (self.question_entry_style, 'Q.TEntry'), self.answer_entry: (self.answer_entry_style, 'A.TEntry'),
                          self.pick_question_entry: (self.pick_question_entry_style, 'QN.TEntry')}

        for wid in entries_widgets:
            if not wid.get().strip() and widget != self.prev_widget:
                wid.delete(0, END)
                wid.insert(END, entries_widgets[wid])
                style, style_name = entries_styles[wid]
                style.configure(style_name, foreground='grey')

        if widget not in widgets:
            self.master.focus()

    def entry_bindings(self, event=None):
        '''When user clicks in or out of the entries widget'''

        widget = event.widget
        entries_widgets = {self.question_entry: 'QUESTION', self.answer_entry: 'ANSWER', self.pick_question_entry: 'QUESTION NUMBER'}
        entries_styles = {self.question_entry: (self.question_entry_style, 'Q.TEntry'), self.answer_entry: (self.answer_entry_style, 'A.TEntry'),
                          self.pick_question_entry: (self.pick_question_entry_style, 'QN.TEntry')}

        if widget in entries_widgets:
            if widget.get().strip() == entries_widgets[widget]:
                widget.delete(0, END)
                self.prev_widget = widget
                style, style_name = entries_styles[widget]
                style.configure(style_name, foreground='black')

                entries_widgets.pop(widget)
                entries_styles.pop(widget)

        for wid in entries_widgets:
            if not wid.get().strip():
                wid.delete(0, END)
                wid.insert(END, entries_widgets[wid])
                style, style_name = entries_styles[wid]
                style.configure(style_name, foreground='grey')

    def read_json(self):
        '''Reading data from the .json file.'''

        try:
            with open(self.file_name, 'r') as f:
                contents = json.load(f)

                if not contents:
                    contents = {}

        except (FileNotFoundError, json.decoder.JSONDecodeError):
            with open(self.file_name, 'w'):
                contents = {}

        return contents

    def write_json(self, contents):
        '''Storing data to the .json file'''

        with open(self.file_name, 'w') as f:
            json.dump(contents, f, indent=4)

    def add_button_command(self, event=None):
        '''When user clicks add question button'''

        question = self.question_entry.get().strip()
        answer = self.answer_entry.get().strip()

        if question in ['', 'QUESTION']:
            messagebox.showerror('Invalid Entry', 'Provide a valid question')

        elif answer in ['', 'ANSWER']:
            messagebox.showerror('Invalid Entry', 'Provide a valid answer')

        else:
            contents = self.read_json()

            if contents:
                head = int(list(contents.keys())[-1]) + 1

            else:
                head = 1

            tail = {'QUESTION': question, 'ANSWER': answer}
            contents[head] = tail

            self.write_json(contents)

            # Setting entry widgets to default
            self.question_entry.focus()
            self.answer_entry.delete(0, END)
            self.question_entry.delete(0, END)
            self.answer_entry.insert(END, 'ANSWER')
            self.question_entry.insert(END, 'QUESTION')
            self.answer_entry_style.configure('A.TEntry', foreground='grey')
            self.question_entry_style.configure('Q.TEntry', foreground='grey')

    def manual_pick_question(self, event=None, question_number=None):
        '''Retrieve the question with respect to the question number provided by the user'''

        contents = self.read_json()

        if not question_number:
            question_number = self.pick_question_entry.get().strip()

        if len(self.quiz_numbers) == len(contents.keys()):
            messagebox.showinfo('No questions', 'No more questions available')

        elif question_number in ['', 'QUESTION NUMBER']:
            messagebox.showerror('Invalid Entry', 'Provide Valid QUESTION NUMBER')

        elif question_number not in contents:
            messagebox.showinfo('Not Found', 'Question number does not exist')

        elif question_number in self.quiz_numbers:
            messagebox.showinfo('Invalid Question Number', 'Question number is already taken')

        else:
            question = contents[question_number]['QUESTION']
            answer = contents[question_number]['ANSWER']
            messagebox.showinfo('Q/A', f'{question_number}. {question}\n\n  Ans. {answer}')

            self.pick_question_entry.delete(0, END)
            self.pick_question_entry.insert(END, 'QUESTION NUMBER')
            self.pick_question_entry_style.configure('QN.TEntry', foreground='grey')

            self.quiz_numbers.append(question_number)

            self.master.focus()

    def random_pick_question(self):
        '''Retrieve question randomly'''

        try:
            all_keys = [value for value in self.read_json().keys() if value not in self.quiz_numbers]
            random_key = random.choice(all_keys)

            self.manual_pick_question(question_number=random_key)

        except IndexError:
            messagebox.showinfo('No questions', 'No more questions available')

    def show_numbers(self, event=None):
        '''Show available question numbers when user presses control-s'''

        numbers = [num for num in self.read_json().keys() if num not in self.quiz_numbers]
        messagebox.showinfo('Valid Numbers', ', '.join(numbers))

    def resource_path(self, relative_path):
        '''Get absolute path to resource from temporary directory

        In development:
            Gets path of files that are used in this script like icons, images or file of any extension from current directory

        After compiling to .exe with pyinstaller and using --add-data flag:
            Gets path of files that are used in this script like icons, images or file of any extension from temporary directory'''

        try:
            base_path = sys._MEIPASS  # PyInstaller creates a temporary directory and stores path of that directory in _MEIPASS

        except AttributeError:
            base_path = os.path.abspath(".")

        return os.path.join(base_path, relative_path)

if __name__ == '__main__':
    Quiz()