Statistiche sulla partecipazione al Bebras italiano 2022/23

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') or r == 'P.A.T.' or 'TRENTO' in r:
        return 'TRENTINO-ALTO ADIGE'
    if r.startswith('LOMB'):
        return 'LOMBARDIA'
    if r.startswith('VALLE') or 'AOSTA' in r:
        return "VALLE D'AOSTA"
    if r == 'G6GG6Y' or r == 'ITALIA':
        return None
    if r == 'ALBANIA' or r == 'BAVIERA' or r == 'SIERRA' or r == 'DDDD' \
       or r == 'FRANCE' or r == 'SVIZZERA' or r == 'CROAZIA' or r == 'ILFOV':
        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]:
from datetime import date
In [6]:
YEAR=2022
LAST_DAY=date(YEAR,11,7)

with open('secret.key') as k:
    key = k.readline().strip()

r = urllib.request.urlopen(("https://bebras.it/api?key={}&view=teachers_edition"+
                           "&edition=bebras_{}&subscription=1").format(key, YEAR))

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)
regteams = teachers['teams_active'].sum()

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

if today <= LAST_DAY:
    isotoday = today.isoformat()[:10]
    with open("stats-" + isotoday + ".txt", "w") as stat:
        stat.write(f"{filled:d} {regteams:d} {3*regteams:d}\n")

2022-11-07: 1009 insegnanti hanno confermato la partecipazione; ci sono 24744 squadre già registrate (~74232 alunni).

In [7]:
oldeditions = (2015, 2016, 2017, "bebras_2018", "bebras_2019", "bebras_2020", "bebras_2021")
In [8]:
oldteachers = {}
for y in oldeditions:
    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 [9]:
intersect = {}
for y in oldeditions:
    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() 
                             )))

44 insegnanti hanno già partecipato all'edizione 2015 (18% dei partecipanti di quell'edizione), il numero di squadre è aumentato in media di 12.6 (deviazione standard 39).

98 insegnanti hanno già partecipato all'edizione 2016 (14% dei partecipanti di quell'edizione), il numero di squadre è aumentato in media di 20.9 (deviazione standard 59).

201 insegnanti hanno già partecipato all'edizione 2017 (19% dei partecipanti di quell'edizione), il numero di squadre è aumentato in media di 17.8 (deviazione standard 57).

278 insegnanti hanno già partecipato all'edizione 2018 (24% dei partecipanti di quell'edizione), il numero di squadre è aumentato in media di 16.4 (deviazione standard 50).

330 insegnanti hanno già partecipato all'edizione 2019 (36% dei partecipanti di quell'edizione), il numero di squadre è aumentato in media di 13.0 (deviazione standard 45).

293 insegnanti hanno già partecipato all'edizione 2020 (59% dei partecipanti di quell'edizione), il numero di squadre è aumentato in media di -20.0 (deviazione standard 74).

516 insegnanti hanno già partecipato all'edizione 2021 (66% dei partecipanti di quell'edizione), il numero di squadre è aumentato in media di -15.6 (deviazione standard 44).

In [10]:
trintersec = pd.merge(intersect["bebras_2019"], oldteachers["bebras_2018"], on='id', how='inner') 
print("Hanno partecipato nel 2018, 2019 e 2020: {}".format(len(trintersec)))
print("Hanno partecipato nel 2017, 2018 e 2020: {}".format(
      len(pd.merge(intersect["bebras_2018"], oldteachers[2017], on='id', how='inner'))))
Hanno partecipato nel 2018, 2019 e 2020: 239
Hanno partecipato nel 2017, 2018 e 2020: 175
In [11]:
all_intersect = pd.merge(teachers['id'], oldteachers[oldeditions[0]]['id'], on='id', how='inner')

for e in oldeditions[1:]:
    all_intersect = pd.merge(all_intersect['id'], oldteachers[e]['id'], on='id', how='inner')

    
print(f"Hanno partecipato a tutte le {len(oldeditions) + 1} edizioni: {len(all_intersect)} insegnanti.")

all_editions = pd.merge(teachers, all_intersect, on='id', how='inner')
#display(all_editions[['firstname', 'name', 'school_name', 'school_city', 'school_kind']])
Hanno partecipato a tutte le 8 edizioni: 28 insegnanti.
In [12]:
#all_editions[all_editions['school_type'] == 'S'].groupby('school_city').count()
In [13]:
institutes = teachers[(teachers['school_code'].str.strip() != "") 
                      & (teachers['subscription'] > 0) 
                      & (teachers['confirm_time'].dt.date > date(2021,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: 434; numero medio insegnanti per codice: 1.90
In [14]:
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 = date(YEAR, 11, 8) - date.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 [15]:
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((date(YEAR-1,11,11) - date(*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 [16]:
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 + ' ' + str(YEAR))
    ax[i].plot([-d.days for d in olddata.index], list(olddata[t]), '--', label=t + ' ' + str(YEAR-1) )
    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(), .75*data[t].max(), '{:+.1f}%'.format(delta*100), color='red' if delta < 0 else 'green')

plt.show()
In [17]:
r = urllib.request.urlopen(("https://bebras.it/api?key={}&view=teams"+
                           "&edition=bebras_{}").format(key, YEAR))
with open("teams.json", "w") as tw:
     tw.writelines(r.read().decode('utf-8'))        
In [18]:
import json
In [19]:
CATS = ('kilo','mega','giga','tera','peta')
CATEGORIES = tuple(f'{c}' for c in CATS)
In [20]:
with open("teams.json") as t:
    teams = pd.DataFrame(json.load(t)['teams'])

oldteams = pd.DataFrame({'class': CATS,f'teams_{YEAR-1}':[4265,14460,6648,5653,3817]})
oldteams.index = oldteams['class']
del oldteams['class']


teams['macro'] = teams['class'].str.slice(0,4)
    
tdata = teams.groupby('macro').count()['login'].copy()

for i in oldteams.index:
    oldteams.loc[i]['teams_' + str(YEAR)] = 1

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

tdata['Incremento %'] = 100*(tdata['login']-tdata[f'teams_{YEAR-1}'])/tdata[f'teams_{YEAR-1}']
display(tdata)

print("In totale {} squadre iscritte ({:+.2f}% rispetto alle squadre iscritte nel {})".format(
    tdata['login'].sum(), 
    100*(tdata['login'].sum()-olddata['squadre'].max())/olddata['squadre'].max(), YEAR-1))
print(f"Nell'edizione {YEAR-1} le squadre avevano 1 o 2 componenti, nel {YEAR} 3.")

students = teams.groupby('class').count().apply(lambda x: 2*x if x.name.endswith('double') else x, axis=1)['login']

print('\nIl numero di partecipanti previsto per categoria:')
display(students)
print(f"Il numero totale di partecipanti previsto è {students.sum()}.")
login teams_2021 Incremento %
kilo 3681 4265 -13.692849
mega 10379 14460 -28.222683
giga 5034 6648 -24.277978
tera 3041 5653 -46.205555
peta 2610 3817 -31.621692
In totale 24745 squadre iscritte (-28.98% rispetto alle squadre iscritte nel 2021)
Nell'edizione 2021 le squadre avevano 1 o 2 componenti, nel 2022 3.

Il numero di partecipanti previsto per categoria:
class
giga     5034
kilo     3681
mega    10379
peta     2610
tera     3041
Name: login, dtype: int64
Il numero totale di partecipanti previsto è 24745.

La popolazione studentesca nazionale

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

In [21]:
istat = pd.read_csv('studenti_italia.csv', 
                usecols=['Territorio', 
                         'Ordine scolastico', 
                         'Value'])
In [22]:
istat = istat.rename(columns={'Territorio':'regione'})
In [23]:
istat['regione'] = istat['regione'].str.upper()
tot_istat = istat.groupby('regione')['Value'].sum()
reg_istat = istat.groupby(['regione', 'Ordine scolastico'])['Value'].sum()
In [24]:
all_istat = reg_istat.unstack()
all_istat['totale'] = tot_istat

all_istat
Out[24]:
Ordine scolastico primaria secondaria I grado secondaria II grado totale
regione
ABRUZZO 55242 34620 56415 146277
BASILICATA 22414 15027 29215 66656
CALABRIA 84815 55363 95406 235584
CAMPANIA 286330 189073 325015 800418
EMILIA-ROMAGNA 200875 123501 191040 515416
FRIULI-VENEZIA GIULIA 50342 32134 48980 131456
ITALIA 2713373 1725037 2690676 7129086
LAZIO 264607 164074 251672 680353
LIGURIA 59281 38247 61394 158922
LOMBARDIA 467791 290789 398786 1157366
MARCHE 66870 41551 70614 179035
MOLISE 11373 7530 13493 32396
PIEMONTE 185943 117185 174388 477516
PUGLIA 180455 118217 203342 502014
SARDEGNA 64028 41152 72712 177892
SICILIA 230417 151877 242549 624843
TOSCANA 159478 100877 162822 423177
TRENTINO ALTO ADIGE / SÃœDTIROL 54774 33977 41538 130289
UMBRIA 37838 24126 37688 99652
VALLE D'AOSTA / VALLÉE D'AOSTE 5789 3610 5528 14927
VENETO 224711 142107 208079 574897
In [25]:
all_istat.loc['VENETO', 'primaria']
Out[25]:
224711

Analisi delle gare

In [26]:
snames = {'E': 'primaria', 'M': 'secondaria I grado', 'S': 'secondaria II grado'}
In [27]:
FIRST=108 # da aggiornare per l'anno corrente

for i, k in enumerate(CATS):
    if not os.path.exists(f"overview-{k}.json"):
        r = urllib.request.urlopen(f"https://bebras.it/api?key={key}&view=exams&test={FIRST+i}&examdata=0&edition=bebras_{YEAR}&events=0")
        with open(f"overview-{k}.json", "w") as tw:
            tw.writelines(r.read().decode('utf-8'))
In [28]:
import json

overview = []
for k in CATEGORIES:
    with open(f"overview-{k}.json", "r") as t:
        j = json.load(t)
        overview += j['exams']
In [29]:
dfov = pd.DataFrame(overview)
In [30]:
gare = pd.DataFrame()
gare['categoria'] = dfov['category'].str.lower().astype(pd.api.types.CategoricalDtype(categories = CATEGORIES, 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 [31]:
fid = teachers.set_index('id')
fid['regione'] = fid['school_region'].map(norm_region)
gare = gare.join(fid[['regione']],on='insegnante')
In [32]:
done = gare[gare['status'] == 1]

Insegnanti partecipanti

In [33]:
len(done.groupby(['insegnante']))
Out[33]:
934

Insegnanti per regione che hanno partecipato

In [34]:
display(done.groupby(['regione'])['insegnante'].nunique())
regione
ABRUZZO                    9
BASILICATA                22
CALABRIA                   5
CAMPANIA                 102
EMILIA-ROMAGNA            56
ESTERO                     2
FRIULI-VENEZIA GIULIA     24
LAZIO                     37
LIGURIA                   23
LOMBARDIA                265
MARCHE                    13
MOLISE                     7
PIEMONTE                  67
PUGLIA                    50
SARDEGNA                   6
SICILIA                   14
TOSCANA                   32
TRENTINO-ALTO ADIGE       41
UMBRIA                     6
VALLE D'AOSTA             39
VENETO                   112
Name: insegnante, dtype: int64

Insegnanti per categoria

In [35]:
display(done.groupby(['categoria'])['insegnante'].nunique())
categoria
kilo    262
mega    475
giga    370
tera    136
peta    113
Name: insegnante, dtype: int64

Squadre per categoria

In [36]:
with pd.option_context('display.float_format', '{:.0f}'.format):
    display(done.groupby(['regione', 'categoria'])['login'].count())
regione                categoria
ABRUZZO                kilo           50
                       mega           24
                       giga            0
                       tera           28
                       peta           64
BASILICATA             kilo          155
                       mega          194
                       giga           93
                       tera           15
                       peta            0
CALABRIA               kilo           23
                       mega            8
                       giga            4
                       tera           31
                       peta           10
CAMPANIA               kilo          372
                       mega          934
                       giga          415
                       tera          158
                       peta          254
EMILIA-ROMAGNA         kilo           87
                       mega          462
                       giga          249
                       tera          265
                       peta          215
ESTERO                 kilo            5
                       mega           11
                       giga            1
                       tera            0
                       peta            0
FRIULI-VENEZIA GIULIA  kilo           55
                       mega           54
                       giga           23
                       tera          362
                       peta          198
LAZIO                  kilo          158
                       mega          365
                       giga          160
                       tera           32
                       peta           39
LIGURIA                kilo           98
                       mega          119
                       giga           57
                       tera           23
                       peta           46
LOMBARDIA              kilo          966
                       mega         2012
                       giga         1082
                       tera          590
                       peta          392
MARCHE                 kilo           10
                       mega           71
                       giga           62
                       tera           78
                       peta          186
MOLISE                 kilo           27
                       mega           14
                       giga            5
                       tera           11
                       peta            0
PIEMONTE               kilo          224
                       mega          647
                       giga          354
                       tera          185
                       peta           82
PUGLIA                 kilo          163
                       mega          494
                       giga          224
                       tera           60
                       peta           38
SARDEGNA               kilo            0
                       mega          158
                       giga           94
                       tera            5
                       peta            9
SICILIA                kilo            9
                       mega           72
                       giga           23
                       tera           34
                       peta          117
TOSCANA                kilo          155
                       mega          390
                       giga          164
                       tera            1
                       peta            4
TRENTINO-ALTO ADIGE    kilo          201
                       mega          480
                       giga          185
                       tera           40
                       peta           18
UMBRIA                 kilo            1
                       mega          196
                       giga           69
                       tera           44
                       peta            0
VALLE D'AOSTA          kilo           61
                       mega          513
                       giga          231
                       tera            0
                       peta            0
VENETO                 kilo          304
                       mega         1167
                       giga          554
                       tera          431
                       peta          307
Name: login, dtype: int64

Studenti per categoria

In [37]:
with pd.option_context('display.float_format', '{:.0f}'.format):
    display(done.groupby(['regione', 'categoria'])['studenti'].sum())
regione                categoria
ABRUZZO                kilo          132
                       mega           30
                       giga            0
                       tera           78
                       peta          181
BASILICATA             kilo          190
                       mega          285
                       giga          180
                       tera            0
                       peta            0
CALABRIA               kilo           64
                       mega           24
                       giga           10
                       tera           85
                       peta           28
CAMPANIA               kilo          681
                       mega         1680
                       giga          788
                       tera          292
                       peta          357
EMILIA-ROMAGNA         kilo          190
                       mega          988
                       giga          549
                       tera          627
                       peta          406
ESTERO                 kilo            0
                       mega           29
                       giga            2
                       tera            0
                       peta            0
FRIULI-VENEZIA GIULIA  kilo          106
                       mega           42
                       giga           14
                       tera          786
                       peta          370
LAZIO                  kilo          175
                       mega          444
                       giga          198
                       tera           91
                       peta          111
LIGURIA                kilo          268
                       mega          203
                       giga           91
                       tera           24
                       peta           27
LOMBARDIA              kilo         2262
                       mega         3872
                       giga         2234
                       tera         1176
                       peta          799
MARCHE                 kilo           27
                       mega          183
                       giga          152
                       tera           50
                       peta          219
MOLISE                 kilo           78
                       mega            0
                       giga            3
                       tera           27
                       peta            0
PIEMONTE               kilo          398
                       mega          754
                       giga          482
                       tera          535
                       peta          224
PUGLIA                 kilo          358
                       mega         1226
                       giga          515
                       tera          167
                       peta          101
SARDEGNA               kilo            0
                       mega           65
                       giga           56
                       tera            0
                       peta            0
SICILIA                kilo           14
                       mega          184
                       giga           57
                       tera           78
                       peta          117
TOSCANA                kilo          382
                       mega          771
                       giga          293
                       tera            3
                       peta            9
TRENTINO-ALTO ADIGE    kilo          487
                       mega          502
                       giga          112
                       tera          118
                       peta           52
UMBRIA                 kilo            1
                       mega          142
                       giga           43
                       tera           94
                       peta            0
VALLE D'AOSTA          kilo          123
                       mega         1100
                       giga          496
                       tera            0
                       peta            0
VENETO                 kilo          871
                       mega         2619
                       giga         1302
                       tera         1131
                       peta          590
Name: studenti, dtype: int64

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 [38]:
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(numeric_only=True)
sregk = done.groupby(['regione','categoria']).sum(numeric_only=True)


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 all_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]] = all_istat.loc[cname, 'totale']
            it.loc[i, 'popolazione ' + TYPES[1]] = all_istat.loc[cname, snames['E']]
            it.loc[i, 'popolazione ' + TYPES[2]] = all_istat.loc[cname, snames['M']]
            it.loc[i, 'popolazione ' + TYPES[3]] = all_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.png')    
plt.show()    

Il Bebras nel mondo (dati 2021)

In [39]:
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 2018)")       
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 2021")       
p = w.dropna(subset=["bebras"]).plot(ax=ax,column='bebras', cmap='YlOrRd', scheme='quantiles', legend=True)
plt.show()

Numeri assoluti

In [40]:
display(wbebras.sort_values("bebras",ascending=False)[["bebras","oecd","copertura"]])
bebras oecd copertura
France 671020 10412016.0 64.446693
Germany 428857 9935909.0 43.162332
United Kingdom 303552 11066193.0 27.430572
Belarus 188307 NaN NaN
Taiwan 175818 NaN NaN
Czech Republic 109442 1370636.0 79.847604
Slovakia 102813 671408.0 153.130436
United States of America 102115 49829312.0 2.049296
Turkey 70107 16384160.0 4.278950
South Korea 59918 5613337.0 10.674221
Ukraine 50712 NaN NaN
Lithuania 50636 349619.0 144.831946
Republic of Serbia 47595 NaN NaN
Italy 47320 7501201.0 6.308323
Portugal 43145 1388754.0 31.067417
Croatia 42553 NaN NaN
China 42373 NaN NaN
Switzerland 36662 1123542.0 32.630734
Hungary 33467 1182406.0 28.304153
Austria 30712 1026408.0 29.921824
Uruguay 30041 NaN NaN
Vietnam 26954 NaN NaN
Indonesia 26831 NaN NaN
Uzbekistan 26744 NaN NaN
Canada 25970 5061204.0 5.131190
Slovenia 24218 276126.0 87.706337
Algeria 24126 NaN NaN
India 22601 NaN NaN
Australia 20790 4627837.0 4.492379
Saudi Arabia 18811 NaN NaN
Latvia 17275 239000.0 72.280335
South Africa 17114 NaN NaN
Poland 15599 4669836.0 3.340374
Netherlands 14914 2807504.0 5.312192
Bosnia and Herzegovina 10865 NaN NaN
Ireland 8307 1056064.0 7.866001
Russia 7339 16217168.0 0.452545
Pakistan 7331 NaN NaN
Romania 6589 NaN NaN
Iran 5670 NaN NaN
Malaysia 5235 NaN NaN
Japan 5139 13500120.0 0.380663
Finland 4944 915321.0 5.401384
Estonia 3889 172124.0 22.594176
Belgium 3612 2000570.0 1.805485
New Zealand 2756 878178.0 3.138316
Colombia 2751 NaN NaN
Iceland 2102 67592.0 31.098355
Philippines 1682 NaN NaN
Israel 1594 NaN NaN
Cyprus 1402 NaN NaN
Spain 1204 6414465.0 0.187701
Jamaica 859 NaN NaN
Bulgaria 671 NaN NaN
Cambodia 611 NaN NaN
Singapore 551 NaN NaN
Niger 303 NaN NaN
Syria 0 NaN NaN
Sweden 0 1828036.0 0.000000
Thailand 0 NaN NaN
Egypt 0 NaN NaN
North Macedonia 0 NaN NaN
Kazakhstan 0 NaN NaN
In [41]:
print("In totale nel mondo {} partecipanti".format(wbebras['bebras'].sum()))
In totale nel mondo 3034518 partecipanti
In [ ]: