Statistiche sulla partecipazione al Bebras italiano 2019/20

In [1]:
from IPython.display import HTML, Markdown

HTML('''<script>
code_show=true; 
function code_toggle() {
 if (code_show){
 $('div.input').hide();
 } else {
 $('div.input').show();
 }
 code_show = !code_show
} 
$( document ).ready(code_toggle);
</script>
<input type="button" value="Clicca per vedere/nascondere il codice Python" onclick="code_toggle()">''')
Out[1]:
In [2]:
import warnings
#warnings.filterwarnings('once')
warnings.filterwarnings('ignore')
In [3]:
%matplotlib inline
import pandas as pd
import urllib.request
from IPython.display import display, Markdown
import matplotlib.pyplot as plt

pd.options.display.max_rows = None
plt.style.use('ggplot')
In [4]:
miur = pd.read_csv('bebras_school_list.zip', low_memory=False)

def norm_region(r):
    """Normalize the name of a region. It also corrects wrong names."""
    r = r.strip().upper()
    if r == 'FVG' or r.startswith('FRIULI'):
        return 'FRIULI-VENEZIA GIULIA'
    if r.startswith('EMILIA'):
        return 'EMILIA-ROMAGNA'
    if r.startswith('TRENTINO') or r.startswith('ALTO ADIGE'):
        return 'TRENTINO-ALTO ADIGE'
    if r.startswith('LOMB'):
        return 'LOMBARDIA'
    if r.startswith('VALLE'):
        return "VALLE D'AOSTA"
    if r == 'G6GG6Y' or r == 'ITALIA':
        return None
    elif r == 'ALBANIA' or r == 'BAVIERA' or r == 'SIERRA' or r == 'DDDD' or r == 'FRANCE':
        return 'ESTERO'
    else:
        return r

def infer_school_type(k):
    knorm = k['school_kind'].strip().upper()
    cnorm = k['school_code'].strip().upper()
    if cnorm and miur[miur['i_code'] == cnorm]['i_type'].count() > 0:
        knorm = str(miur[miur['i_code'] == cnorm]['i_type'].iloc[0])
    if 'PRIMARIA' in knorm or 'INFANZIA' in knorm or 'ELEMENTARE' in knorm:
        return 'E'
    if 'PRIMO GRADO' in knorm or ('MEDIA' in knorm and (not 'SUP' in knorm))\
    or '1°' in knorm or ' I GRADO' in knorm or knorm == 'IC':
        return 'M'
    if 'COMPRENSIVO' in knorm:
        return 'EM'
    if 'SECONDO GRADO' in knorm or '2°' in knorm  or 'II GRADO' in knorm \
    or 'LICEO' in knorm or 'ITI' in knorm or 'PROF' in knorm or 'IST TEC' in knorm \
    or 'TECNICO' in knorm or 'MAGISTRALE' in knorm or 'SUPERIORE' in knorm:
        return 'S'
    if knorm == 'STATALE' or 'C.D.38':
        return 'EMS'
    else:
        return knorm
   

Insegnanti, stima delle squadre e alunni

In [5]:
with open('secret.key') as k:
    key = k.readline().strip()

r = urllib.request.urlopen(("https://bebras.it/api?key={}&view=teachers_edition"+
                           "&edition=bebras_2019&subscription=1").format(key))
with open("teachers.json", "w") as tw:
     tw.writelines(r.read().decode('utf-8'))        

teachers = pd.DataFrame(pd.read_json("teachers.json", convert_axes=True))

teachers.index = range(len(teachers))
teachers['confirm_time'] = pd.to_datetime(teachers['confirm_time'], unit='s')
teachers['enter_time'] = pd.to_datetime(teachers['enter_time'], unit='s')

teachers['school_code'] = teachers['school_code'].str.strip().str.upper()
teachers['school_type'] = teachers[['school_kind','school_code']].apply(infer_school_type, axis=1)
filled = len(teachers)
expected = teachers.sum()
regteams = expected['teams_active']

today = pd.datetime.today()
if today > pd.datetime(2019,11,11):
    today = pd.datetime(2019,11,11)
s = """*{}:* **{:d}** insegnanti hanno confermato la partecipazione; 
ci sono **{:d}** squadre già registrate (~*{:d}* alunni).
"""
display(Markdown(s.format(str(today)[:19], 
                          filled, regteams, regteams*4)))

if today <= pd.datetime(2019,11,11):
    isotoday = today.isoformat()[:10]
    with open("stats-" + isotoday + ".txt", "w") as stat:
        stat.write("{:d} {:d} {:d}\n".format(filled, regteams, regteams*4))

2019-11-11 00:00:00: 957 insegnanti hanno confermato la partecipazione; ci sono 17596 squadre già registrate (~70384 alunni).

In [6]:
oldteachers = {}
for y in [2015, 2016, 2017, "bebras_2018"]:
    r = urllib.request.urlopen(("https://bebras.it/api?key={}&view=teachers_edition"+
                                "&edition={}").format(key, y))
    with open("teachers{}.json".format(y), "w") as tw:
        tw.writelines(r.read().decode('utf-8'))

    oldteachers[y] = pd.DataFrame(pd.read_json("teachers{}.json".format(y), convert_axes=True))[3:]
    #oldtteachers[y]['school_type'] = oldteachers[['school_kind','school_code']].apply(infer_school_type, axis=1)
In [7]:
intersect = {}
for y in [2015, 2016, 2017, "bebras_2018"]:
    intersect[y] = pd.merge(teachers, oldteachers[y], on='id', how='inner')
    intersect[y]['deltateams'] = intersect[y]['teams_active_x'] - intersect[y]['teams_active_y']
    returning = intersect[y]['id'].count()
    base = len(oldteachers[y][oldteachers[y]['teams_active'] > 0])
    s = """*{:d}* insegnanti hanno già partecipato all'edizione {} (**{:.0f}%** dei partecipanti di quell'edizione), 
il numero di squadre è aumentato in media di {:.1f} (deviazione standard {:.0f}).
"""
    display(Markdown(s.format(returning, str(y)[-4:], 
                              100*float(returning)/float(base),
                              intersect[y]['deltateams'].mean(), intersect[y]['deltateams'].std() 
                             )))

77 insegnanti hanno già partecipato all'edizione 2015 (32% dei partecipanti di quell'edizione), il numero di squadre è aumentato in media di 7.8 (deviazione standard 22).

181 insegnanti hanno già partecipato all'edizione 2016 (25% dei partecipanti di quell'edizione), il numero di squadre è aumentato in media di 8.7 (deviazione standard 28).

357 insegnanti hanno già partecipato all'edizione 2017 (34% dei partecipanti di quell'edizione), il numero di squadre è aumentato in media di 5.7 (deviazione standard 21).

550 insegnanti hanno già partecipato all'edizione 2018 (48% dei partecipanti di quell'edizione), il numero di squadre è aumentato in media di 3.2 (deviazione standard 16).

In [8]:
trintersec = pd.merge(intersect["bebras_2018"], oldteachers[2017], on='id', how='inner') 
print("Hanno partecipato nel 2017, 2018 e 2019: {}".format(len(trintersec)))
print("Hanno partecipato nel 2016, 2018 e 2019: {}".format(
      len(pd.merge(intersect["bebras_2018"], oldteachers[2016], on='id', how='inner'))))
print("Hanno partecipato nel 2016, 2017 e 2019: {}".format(
      len(pd.merge(intersect[2017], oldteachers[2016], on='id', how='inner'))))
print("Hanno partecipato nel 2016, 2017, 2018 e 2019: {}".format(
      len(pd.merge(trintersec, oldteachers["bebras_2018"], on='id', how='inner'))))
Hanno partecipato nel 2017, 2018 e 2019: 325
Hanno partecipato nel 2016, 2018 e 2019: 165
Hanno partecipato nel 2016, 2017 e 2019: 156
Hanno partecipato nel 2016, 2017, 2018 e 2019: 325
In [9]:
institutes = teachers[(teachers['school_code'].str.strip() != "") 
                      & (teachers['subscription'] > 0) 
                      & (teachers['confirm_time'] > pd.datetime(2019,9,1))].groupby('school_code')['id'].count()

print("Totale istituti con codice meccanografico: {}; numero medio insegnanti per codice: {:.2f}".format(len(institutes), institutes.mean()))
Totale istituti con codice meccanografico: 466; numero medio insegnanti per codice: 1.64
In [10]:
import os
data = []
for path, dirs, files in os.walk("."):
    for f in files:
        if path == '.' and f.startswith("stats-"):
            d = [int(x) for x in f.split('.')[0].split('-')[1:4]]
            with open(f,"r") as df:
                nn = [int(x) for x in df.readline().strip().split(" ")]
                dd = pd.datetime(2019, 11, 11) - pd.datetime.fromtimestamp(os.stat(f).st_mtime)
                data.append((dd, nn))
data = pd.DataFrame.from_dict(dict(data), orient="index", 
                               columns=["insegnanti","squadre","alunni"]).sort_index(ascending=False)
data['giorni'] = (data.index * -1).astype('timedelta64[D]')
In [11]:
olddata = []
for path, dirs, files in os.walk("old"):
    for f in files:
        if f.startswith("stats-"):
            d = [int(x) for x in f.split('.')[0].split('-')[1:4]]
            with open(path + "/" + f,"r") as df:
                nn = [int(x) for x in df.readline().strip().split(" ")]
                olddata.append((pd.datetime(2018,11,12) - pd.datetime(*d), nn))
olddata = pd.DataFrame.from_dict(dict(olddata), orient="index", 
                                  columns=["insegnanti","squadre","alunni"]).sort_index(ascending=False)
olddata['giorni'] = (olddata.index * -1).astype('timedelta64[D]')
In [12]:
fig, ax = plt.subplots(1,2)
fig.set_size_inches(11,5)

for i, t in enumerate(['squadre', 'insegnanti']):
    ax[i].plot([-d.days for d in data.index], list(data[t]), label=t + ' 2019')
    ax[i].plot([-d.days for d in olddata.index], list(olddata[t]), '--', label=t + ' 2018')
    ax[i].legend()
    ax[i].set_xlim([-50,0])
    delta = (data[t].max()-olddata[t].max())/olddata[t].max()
    ax[i].text(-.9*data[t].count(), .9*data[t].max(), '{:+.1f}%'.format(delta*100), color='tomato')

plt.show()
In [13]:
r = urllib.request.urlopen(("https://bebras.it/api?key={}&view=teams"+
                           "&edition=bebras_2019").format(key))
with open("teams.json", "w") as tw:
     tw.writelines(r.read().decode('utf-8'))        
In [14]:
import json

with open("teams.json") as t:
    teams = pd.DataFrame(json.load(t)['teams'])

oldteams = pd.DataFrame({'class':['kilo','mega','giga','tera','peta'],'teams_2018':[3770,5592,2651,2070,1655]})
oldteams.index = oldteams['class']
del oldteams['class']
    
tdata = teams.groupby('class').count()['login'].copy()
#tdata['teams_2019'] = tdata['login']
#del tdata['login']

for i in oldteams.index:
    oldteams.loc[i]['teams_2019'] = 1

tdata = pd.concat([tdata, oldteams],axis=1)


tdata['Incremento %'] = 100*(tdata['login']-tdata['teams_2018'])/tdata['teams_2018']
display(tdata)
print("In totale {} squadre iscritte ({:+.2f}% rispetto alle squadre partecipanti nel 2018)".format(
    tdata['login'].sum(), 
    100*(tdata['login'].sum()-tdata['teams_2018'].sum())/tdata['teams_2018'].sum()))
print("In totale {} squadre iscritte ({:+.2f}% rispetto alle squadre iscritte nel 2018)".format(
    tdata['login'].sum(), 
    100*(tdata['login'].sum()-olddata['squadre'].max())/olddata['squadre'].max()))
login teams_2018 Incremento %
giga 3224 2651 21.614485
kilo 3464 3770 -8.116711
mega 6476 5592 15.808298
peta 1917 1655 15.830816
tera 2515 2070 21.497585
In totale 17596 squadre iscritte (+11.81% rispetto alle squadre partecipanti nel 2018)
In totale 17596 squadre iscritte (-1.51% rispetto alle squadre iscritte nel 2018)

La popolazione studentesca nazionale

Dati ISTAT della popolazione studentesca scuola primaria e secondaria nel 2014 (fonte: http://dati.istat.it)

In [15]:
istat = pd.DataFrame.from_dict(
    dict([
    ("PIEMONTE",              (191399, 117997, 168439)),
    ("VALLE D'AOSTA",         (  5981,   3691,   5309)),
    ("LIGURIA",               ( 61566,  39213,  60184)),
    ("LOMBARDIA",             (468662, 283007, 381619)),
    ("TRENTINO-ALTO ADIGE",   ( 27028,  16890,  21836)),
    ("VENETO",                (232694, 142401, 204262)),
    ("FRIULI-VENEZIA GIULIA", ( 51830,  32143,  46949)),
    ("EMILIA-ROMAGNA",        (198417, 118460, 176968)),
    ("TOSCANA",               (161001,  98203, 152886)),
    ("UMBRIA",                ( 39181,  23488,  36946)),
    ("MARCHE",                ( 67996,  42095,  70602)),
    ("LAZIO",                 (268133, 161573, 249145)),
    ("ABRUZZO",               ( 57146,  35828,  58578)),
    ("MOLISE",                ( 12595,   8354,  14990)),
    ("CAMPANIA",              (317346, 204223, 326644)),
    ("PUGLIA",                (198662, 130675, 213545)),
    ("BASILICATA",            (25237,  17097,   30214)),
    ("CALABRIA",              (93277,  59624,  101208)),
    ("SICILIA",               (254023, 164520, 252730)),
    ("SARDEGNA",              (67379,  44105,   74003)),
    ("ESTERO",       (pd.np.NaN, pd.np.NaN, pd.np.NaN))
    ]),
    orient = "index",
    columns = ('Primaria','Secondaria I grado','Secondaria II grado'))
istat['totale'] = istat['Primaria'] + istat['Secondaria I grado'] + istat['Secondaria II grado']
with pd.option_context('display.float_format', '{:.0f}'.format):
    display(istat)
Primaria Secondaria I grado Secondaria II grado totale
PIEMONTE 191399 117997 168439 477835
VALLE D'AOSTA 5981 3691 5309 14981
LIGURIA 61566 39213 60184 160963
LOMBARDIA 468662 283007 381619 1133288
TRENTINO-ALTO ADIGE 27028 16890 21836 65754
VENETO 232694 142401 204262 579357
FRIULI-VENEZIA GIULIA 51830 32143 46949 130922
EMILIA-ROMAGNA 198417 118460 176968 493845
TOSCANA 161001 98203 152886 412090
UMBRIA 39181 23488 36946 99615
MARCHE 67996 42095 70602 180693
LAZIO 268133 161573 249145 678851
ABRUZZO 57146 35828 58578 151552
MOLISE 12595 8354 14990 35939
CAMPANIA 317346 204223 326644 848213
PUGLIA 198662 130675 213545 542882
BASILICATA 25237 17097 30214 72548
CALABRIA 93277 59624 101208 254109
SICILIA 254023 164520 252730 671273
SARDEGNA 67379 44105 74003 185487
ESTERO nan nan nan nan

Analisi delle gare

In [16]:
CATS = ('kilo', 'mega', 'giga', 'tera', 'peta')
snames = {'E': 'Primaria', 'M': 'Secondaria I grado', 'S': 'Secondaria II grado'}
In [17]:
for i, k in enumerate(CATS):
    if not os.path.exists("overview-{}.json".format(k)):
        r = urllib.request.urlopen("https://bebras.it/api?key={}&view=exams&test={}&examdata=0&edition=bebras_2019&events=0".format(key,85+i))
        with open("overview-{}.json".format(k), "w") as tw:
            tw.writelines(r.read().decode('utf-8'))
In [18]:
import json

overview = []
for k in CATS:
    with open("overview-{}.json".format(k), "r") as t:
        j = json.load(t)
        overview += j['exams']
In [19]:
dfov = pd.DataFrame(overview)
gare = pd.DataFrame()
gare['categoria'] = dfov['category'].str.lower().astype(pd.api.types.CategoricalDtype(categories = CATS, ordered=True))
gare['insegnante'] = dfov['teacher_id'].astype('int64')
gare['login'] = dfov['login']
gare['status'] = dfov['exam_valid_score']
gare['risultato'] = dfov['score']
gare['data'] = pd.to_datetime(dfov['time'])
gare['studenti'] = dfov['team_composition'].map(lambda tt: 0 if type(tt) != type({}) else len([s for s in tt['members'] if s['name'] != '' ]))
In [20]:
fid = teachers.set_index('id')
fid['regione'] = fid['school_region'].map(norm_region)
gare = gare.join(fid[['regione']],on='insegnante')
In [21]:
done = gare[gare['status'] == 1]

Insegnanti partecipanti

In [22]:
len(done.groupby(['insegnante']))
Out[22]:
875

Insegnanti per regione che hanno partecipato

In [23]:
display(done.groupby(['regione'])['insegnante'].nunique())
regione
ABRUZZO                                   9
BASILICATA                               10
CALABRIA                                 18
CAMPANIA                                 91
EMILIA-ROMAGNA                           52
FRIULI-VENEZIA GIULIA                    18
LAZIO                                    75
LIGURIA                                  26
LOMBARDIA                               236
MARCHE                                   10
MOLISE                                    4
PIEMONTE                                 53
PUGLIA                                   59
REGIONE AUTONOMA DELLA VALLE D'AOSTA      1
SARDEGNA                                  9
SICILIA                                  31
TOSCANA                                  34
TRENTINO-ALTO ADIGE                      12
UMBRIA                                    7
VALLE D'AOSTA                            24
VENETO                                   96
Name: insegnante, dtype: int64

Insegnanti per categoria

In [24]:
display(done.groupby(['categoria'])['insegnante'].nunique())
categoria
kilo    276
mega    404
giga    323
tera    144
peta    122
Name: insegnante, dtype: int64

Squadre per categoria

In [25]:
with pd.option_context('display.float_format', '{:.0f}'.format):
    display(done.groupby(['regione', 'categoria'])['login'].count())
regione                               categoria
ABRUZZO                               kilo           26
                                      mega           33
                                      giga           19
                                      peta            8
BASILICATA                            mega           53
                                      giga           28
                                      tera           14
CALABRIA                              kilo           67
                                      mega           84
                                      giga           36
                                      tera           53
                                      peta           25
CAMPANIA                              kilo          391
                                      mega          573
                                      giga          257
                                      tera           64
                                      peta           26
EMILIA-ROMAGNA                        kilo           53
                                      mega          347
                                      giga          185
                                      tera          195
                                      peta          119
FRIULI-VENEZIA GIULIA                 kilo           56
                                      mega           86
                                      giga           37
                                      tera          155
                                      peta           49
LAZIO                                 kilo          408
                                      mega          213
                                      giga          123
                                      tera          159
                                      peta          212
LIGURIA                               kilo           78
                                      mega           89
                                      giga           51
                                      tera          170
                                      peta          204
LOMBARDIA                             kilo          871
                                      mega         1400
                                      giga          745
                                      tera          578
                                      peta          317
MARCHE                                kilo            7
                                      mega          121
                                      giga           62
                                      tera           51
                                      peta           46
MOLISE                                kilo           14
                                      mega            6
                                      giga            5
                                      tera           11
                                      peta            8
PIEMONTE                              kilo          113
                                      mega          446
                                      giga          159
                                      tera          139
                                      peta           75
PUGLIA                                kilo          501
                                      mega          498
                                      giga          223
                                      tera           13
                                      peta           11
REGIONE AUTONOMA DELLA VALLE D'AOSTA  mega           21
SARDEGNA                              kilo           27
                                      mega          148
                                      giga           58
                                      tera            7
                                      peta            1
SICILIA                               kilo           42
                                      mega          132
                                      giga           53
                                      tera           47
                                      peta           57
TOSCANA                               kilo           73
                                      mega          270
                                      giga          110
                                      tera           84
                                      peta            4
TRENTINO-ALTO ADIGE                   kilo           21
                                      mega          232
                                      giga          104
                                      tera           17
                                      peta            9
UMBRIA                                mega           17
                                      giga            4
                                      tera           62
                                      peta            1
VALLE D'AOSTA                         kilo           41
                                      mega          212
                                      giga          100
VENETO                                kilo          255
                                      mega          747
                                      giga          350
                                      tera          253
                                      peta          309
Name: login, dtype: int64

Studenti per categoria

In [26]:
with pd.option_context('display.float_format', '{:.0f}'.format):
    display(done.groupby(['regione', 'categoria'])['studenti'].sum())
regione                               categoria
ABRUZZO                               kilo          70
                                      mega          43
                                      giga           0
                                      tera         nan
                                      peta          32
BASILICATA                            kilo         nan
                                      mega         151
                                      giga         104
                                      tera          56
                                      peta         nan
CALABRIA                              kilo         228
                                      mega         162
                                      giga          68
                                      tera         191
                                      peta          94
CAMPANIA                              kilo        1179
                                      mega        1918
                                      giga         920
                                      tera         196
                                      peta          93
EMILIA-ROMAGNA                        kilo         165
                                      mega        1203
                                      giga         641
                                      tera         699
                                      peta         405
FRIULI-VENEZIA GIULIA                 kilo         172
                                      mega          52
                                      giga          27
                                      tera         472
                                      peta         149
LAZIO                                 kilo         924
                                      mega         605
                                      giga         345
                                      tera         562
                                      peta         751
LIGURIA                               kilo         268
                                      mega         269
                                      giga         146
                                      tera         194
                                      peta         258
LOMBARDIA                             kilo        2795
                                      mega        4144
                                      giga        2132
                                      tera        1832
                                      peta        1085
MARCHE                                kilo          28
                                      mega         351
                                      giga         218
                                      tera         173
                                      peta         161
MOLISE                                kilo          56
                                      mega          24
                                      giga          20
                                      tera          34
                                      peta          28
PIEMONTE                              kilo         374
                                      mega        1212
                                      giga         459
                                      tera         522
                                      peta         275
PUGLIA                                kilo        1570
                                      mega        1677
                                      giga         764
                                      tera          46
                                      peta          40
REGIONE AUTONOMA DELLA VALLE D'AOSTA  kilo         nan
                                      mega          63
                                      giga         nan
                                      tera         nan
                                      peta         nan
SARDEGNA                              kilo          85
                                      mega         151
                                      giga          74
                                      tera          24
                                      peta           4
SICILIA                               kilo         155
                                      mega         373
                                      giga          94
                                      tera         140
                                      peta         193
TOSCANA                               kilo         239
                                      mega         916
                                      giga         311
                                      tera          31
                                      peta          16
TRENTINO-ALTO ADIGE                   kilo           0
                                      mega         396
                                      giga         151
                                      tera          23
                                      peta          20
UMBRIA                                kilo         nan
                                      mega          17
                                      giga           0
                                      tera         236
                                      peta           0
VALLE D'AOSTA                         kilo         137
                                      mega         722
                                      giga         311
                                      tera         nan
                                      peta         nan
VENETO                                kilo         779
                                      mega        2306
                                      giga        1080
                                      tera         791
                                      peta         869
Name: studenti, dtype: float64

Cartografia ISTAT 2011 (fonte: http://www.istat.it/it/archivio/24613), convertita con il comando:

ogr2ogr -f GeoJSON -s_srs reg2011_g.prj -t_srs EPSG:4326 it.json reg2011_g.shp

(fonte: https://gist.github.com/riccardoscalco/6029355)

In [27]:
import geopandas as gpd
%matplotlib inline

it = gpd.read_file("it.json")

TYPES = ['totale'] + list(snames.values())

dreg = done.groupby(['regione']).count()
dregk = done.groupby(['regione','categoria']).count()

sreg = done.groupby(['regione']).sum()
sregk = done.groupby(['regione','categoria']).sum()


def get_data_with_default(geo, i, t, ddata, sdata, jj, labeld='login', labels='studenti'):
    try:
        geo.loc[i, 'squadre' + ' ' + t] = 0
        for j in jj:
            geo.loc[i, 'squadre' + ' ' + t] += ddata.loc[j, labeld] if ddata.loc[j, labeld] > 0 else 0 
    except:
        geo.loc[i, 'squadre' + ' ' + t] += 0
    try:
        geo.loc[i, 'studenti' + ' ' + t] = 0
        for j in jj:
            geo.loc[i, 'studenti' + ' ' + t] += sdata.loc[j, labels] if sdata.loc[j, labels] > 0 else 0
    except:
        geo.loc[i, 'studenti' + ' ' + t] += 0

        
for i, r in it.iterrows():
    for cname in istat.index:
        if r['NOME_REG'][0:5] == cname[0:5]:
            it.loc[i, 'NOME_REG'] = cname
            get_data_with_default(it, i, TYPES[0], dreg, sreg, [cname])
            get_data_with_default(it, i, TYPES[1], dregk, sregk, [(cname, 'kilo')])
            get_data_with_default(it, i, TYPES[2], dregk, sregk, [(cname, 'mega'), (cname, 'giga')])
            get_data_with_default(it, i, TYPES[3], dregk, sregk, [(cname, 'tera'), (cname, 'peta')])
                
            it.loc[i, 'popolazione ' + TYPES[0]] = istat.loc[cname, 'totale']
            it.loc[i, 'popolazione ' + TYPES[1]] = istat.loc[cname, snames['E']]
            it.loc[i, 'popolazione ' + TYPES[2]] = istat.loc[cname, snames['M']]
            it.loc[i, 'popolazione ' + TYPES[3]] = istat.loc[cname, snames['S']]
            break

for t in TYPES:
    it['copertura ' + t] = 1000 * it['studenti ' + t] / it['popolazione ' + t]

fig, ax = plt.subplots(2,2)
fig.set_size_inches(15,11)
for i, t in enumerate(TYPES):
    r = i // 2
    c = i % 2
    ax[r][c].set_aspect("equal")
    ax[r][c].set_axis_off()
    ax[r][c].set_title("Studenti ogni mille ({})".format(t))
    it.plot(ax=ax[r][c], column='copertura ' + t, cmap='YlOrRd', scheme='quantiles', legend=True)
    
fig.savefig('italia.pdf')    
plt.show()    

Il Bebras nel mondo (dati 2018)

In [28]:
w = gpd.read_file("world.json")
w = w.set_index("name")

with open("wbebras.json", "r") as t:
    wbebras = pd.DataFrame(pd.read_json(t, convert_axes=True, orient='index'))

wbebras['copertura'] = 1000 * wbebras["bebras"] / wbebras["oecd"]    
    
for i in wbebras.index:
    try:
        w.loc[i, "bebras"] = wbebras.loc[i, "bebras"]
        w.loc[i, "oecd"]   = wbebras.loc[i, "oecd"]
        w.loc[i, "copertura"]   = wbebras.loc[i, "copertura"]
    except:
        print(i)

plt.figure(figsize=(20,20))
ax = plt.subplot(212)
ax.set_aspect("equal")
ax.set_axis_off()
ax.set_title("Partecipanti ogni 1000 studenti (dati OECD 2015)")       
w.dropna().plot(ax=ax,column='copertura', cmap='Blues', scheme='quantiles', legend=True)


ax = plt.subplot(211)
ax.set_aspect("equal")
ax.set_axis_off()
ax.set_title("Partecipanti Bebras 2018")       
p = w.dropna(subset=["bebras"]).plot(ax=ax,column='bebras', cmap='YlOrRd', scheme='quantiles', legend=True)
plt.show()

Numeri assoluti

In [29]:
display(wbebras.sort_values("bebras",ascending=False)[["bebras","oecd","copertura"]])
bebras oecd copertura
France 682053 10075812.0 67.692113
Germany 373406 10351237.0 36.073563
United Kingdom 201911 48504360.0 4.162739
Belarus 150237 NaN NaN
India 137081 NaN NaN
Taiwan 118332 NaN NaN
Ukraine 117885 NaN NaN
China 104573 NaN NaN
Czech Republic 79988 NaN NaN
Slovakia 77928 727693.0 107.089116
Turkey 68484 NaN NaN
Italy 51297 7461117.0 6.875244
Republic of Serbia 50168 NaN NaN
United States of America 46699 48504360.0 0.962779
Lithuania 44136 NaN NaN
Australia 43163 4460447.0 9.676833
Slovenia 33590 256122.0 131.148437
Austria 32675 1041322.0 31.378382
Hungary 25464 1310996.0 19.423400
South Korea 25455 NaN NaN
North Macedonia 25372 NaN NaN
Croatia 22887 NaN NaN
Poland 22540 5085090.0 4.432567
Switzerland 21313 NaN NaN
South Africa 21035 11848282.0 1.775363
Canada 18874 4950935.0 3.812209
Netherlands 18852 NaN NaN
Latvia 17574 250298.0 70.212307
Romania 14976 NaN NaN
Greece 13905 NaN NaN
Vietnam 12957 NaN NaN
Russia 12909 14774916.0 0.873711
Bosnia and Herzegovina 9732 NaN NaN
Pakistan 8754 NaN NaN
Ireland 6851 861872.0 7.948976
Malaysia 6815 NaN NaN
Tunisia 5708 NaN NaN
Finland 5613 896483.0 6.261134
Sweden 5499 NaN NaN
Japan 5128 14212385.0 0.360812
Indonesia 4677 NaN NaN
Kazakhstan 4671 NaN NaN
Hong Kong 4659 NaN NaN
Belgium 4400 1935904.0 2.272840
Iran 4161 NaN NaN
Thailand 4132 NaN NaN
Estonia 3458 159432.0 21.689498
New Zealand 2754 849060.0 3.243587
Nigeria 2500 NaN NaN
Philippines 2236 NaN NaN
Egypt 1416 NaN NaN
Iceland 1357 NaN NaN
Singapore 1352 NaN NaN
Spain 965 6206261.0 0.155488
Algeria 796 NaN NaN
Cyprus 526 NaN NaN
Bulgaria 514 NaN NaN
In [30]:
print("In totale nel mondo {} partecipanti".format(wbebras['bebras'].sum()))
In totale nel mondo 2786393 partecipanti