import pandas as pd
import numpy as np

def llegeixCens() :
    df = pd.read_csv(
        'TAULA_MAP_SCENSAL.csv',
        dtype={'SECCIO_CENSAL':str}
    )
    df.set_index('SECCIO_CENSAL', inplace=True)
    return df

def llegeixAdreces():
    df = pd.read_csv(
        "TAULA_DIRELE_SEC_CENS.csv",
        usecols = ['NOM_CARRER', 'PRIMER_NUM', 'ULTIM_NUM', 'DISTRICTE', 'SECC_CENS'],
        dtype={'DISTRICTE':str,'SECC_CENS':str}
    )
    df['SECCIO_CENSAL']= df['DISTRICTE'] + df['SECC_CENS']
    return df.drop(['DISTRICTE', 'SECC_CENS'], axis = 1)


def buscaSecció_1(df, adr):
    nom, num = adr
    pe = pd.to_numeric(df['PRIMER_NUM'], errors='coerce')
    ue = pd.to_numeric(df['ULTIM_NUM'], errors='coerce')
    sc = df[(df['NOM_CARRER'] == nom) & (pe <= num) & (num <= ue)]
    lsc = len(sc)
    if lsc == 0:
        r = -1
    elif lsc == 1:
        r = sc.iloc[0]['SECCIO_CENSAL']
    elif lsc == 2:
        if int(sc.iloc[0]['PRIMER_NUM'])%2 == num%2:
            r = sc.iloc[0]['SECCIO_CENSAL']
        elif int(sc.iloc[1]['PRIMER_NUM'])%2 == num%2:
            r = sc.iloc[1]['SECCIO_CENSAL']
        else:
            assert False, "Dos resultats, però cap té la paritat adequada"
    else:
        assert False, "Més de dos resultats"
    return r

def buscaSecció_2(df, adreça) :
    #
    # No té en compte parells i senars
    #
    df2 = df[df['NOM_CARRER'].str.contains(adreça[0])]

    n2_ant  = 0
    for row in df2.itertuples() :
        try :
            n1 = int(row[2])
            n2 = int(row[3])
            if n1<= adreça[1] <= n2 and n1%2 == adreça[1]%2 :
                return row[4]
        except :
            pass
    return -1

#
# Tria la solució que vulguis provar
#
buscaSecció = buscaSecció_1
# buscaSecció = buscaSecció_2


def percentatgeGentGran_1(df, sec):
    row= df.loc[sec]
    total = row[['EDAT_0_A_14', 'EDAT_15_A_24', 'EDAT_25_A_64','EDAT_65_A_MES']].sum()
    return row['EDAT_65_A_MES']/total*100

def percentatgeGentGran_2(df, sc):
    ssc = df.loc[sc]
    total = ssc['HOMES'] + ssc['DONES']
    m65 = ssc['EDAT_65_A_MES']
    return float(m65/total*100)

#
# Tria la solució que vulguis provar
#
# percentatgeGentGran = percentatgeGentGran_1
percentatgeGentGran = percentatgeGentGran_2


def decilPercentatge_1(df, p65):
    total = df['HOMES'] + df['DONES']
    m65 = df['EDAT_65_A_MES']
    pu65 = m65/total
    a = np.linspace(0, 1, 11)
    pct = pu65.quantile(a)
    pctm65 = pct[pct > p65/100]
    return int(pctm65.index[0]*10)

def quantil_invers(perc, df) :
    s =  pd.Series(range(0, 101, 10))/100
    s = s.apply(lambda x: df.quantile(x))
    for i in range(len(s)):
        if perc <= s.iat[i] :
            return i
    return -1
        
def decilPercentatge_2(df, perc):
    df2 = df['EDAT_65_A_MES']/df[['EDAT_0_A_14', 'EDAT_15_A_24', 'EDAT_25_A_64','EDAT_65_A_MES']].sum(axis=1)*100
    return quantil_invers(perc, df2)

#
# Tria la solució que vulguis provar
#
decilPercentatge = decilPercentatge_1
# decilPercentatge = decilPercentatge_2


def comÉsElBarri(adreça) :
    df = llegeixAdreces()
    s = buscaSecció(df, adreça)
    if s != -1 :
        df2 = llegeixCens()
        p = percentatgeGentGran(df2, s)
        d = decilPercentatge(df2, p)
        return d
    else :
        return -1
