import lxml.html
import urllib.request
import requests
import json
import re
import plotly.offline as py
py.init_notebook_mode(connected=True)
from jupyterthemes import jtplot
jtplot.style()
html_url = "https://zpm-mb.si/raziskovalne-naloge/"
api_url = "https://zpm-mb.si/wp-admin/admin-ajax.php"
html = requests.get(html_url).content
zpm_html = lxml.html.fromstring(html)
#zpm.make_links_absolute()
leta_html = zpm_html.cssselect("#naloga_leto > option")
leta = [];
for leto in leta_html:
if leto.attrib["value"].isdigit():
leta.append(leto.attrib["value"])
leta
['2011', '2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020', '2021']
aad_nonce = re.search("\"aad_nonce\":\"([0-9a-f]{10})\"};", zpm_html.text_content()).group(1)
aad_nonce
'989a042ef2'
from ipywidgets import FloatProgress, interact
from IPython.display import display
bar = FloatProgress(min=0, max=len(leta))
display(bar)
htmls = {}
for leto in leta:
data = {
"action": "aad_get_results03",
"dataType": "json",
"value_leto": leto,
"value_vrsta_sola": "",
"value_vrsta_naloge": "",
"value_predmet": "",
"value_sola": "",
"aad_nonce": aad_nonce
}
resp = requests.post(api_url, data, allow_redirects=False)
response = resp.json()
htmls[leto] = response["result3"]
bar.value += 1
resp.request.body
'action=aad_get_results03&dataType=json&value_leto=&value_vrsta_sola=Srednja%2B%C5%A1ola&value_vrsta_naloge=&value_predmet=&value_sola=&aad_nonce=989a042ef2'
import traceback
bar = FloatProgress(min=0, max=len(leta))
display(bar)
podatki = []
for leto, html in htmls.items():
dom = lxml.html.fragment_fromstring(html, create_parent=True)
tabele = dom.cssselect(".large-3 > .raz_naloga_table")
for tabela in tabele:
try:
naslov = tabela.cssselect("tr > th")[1].text_content()
naloga = {"Naslov naloge": naslov, "Leto": leto}
#print naslov + ":"
for tr in tabela.cssselect("tr"):
tds = tr.cssselect("td")
if len(tds) < 2:
continue
index = tds[0].text_content().replace(":", "")
value = tds[1].text_content()
naloga[index] = value
#print "\t" + index + ": \t" + value
if naloga["Vrsta naloge"] != "Zbornik":
naloga["Točke"] = int(naloga["Točke"])
podatki.append(naloga)
#print(naloga)
except:
traceback.print_exc()
print(lxml.html.tostring(tabela))
bar.value += 1
Traceback (most recent call last): File "<ipython-input-88-30fedb1a0ad0>", line 27, in <module> naloga["Točke"] = int(naloga["Točke"]) ValueError: invalid literal for int() with base 10: ''
b'<table class="raz_naloga_table"><tr><th><img src="https://zpm-mb.si/wp-content/themes/advocator-child/images/raz_naloge.jpg" style="width: 40px; position: absolute; margin: 10px 3px;"></th><th>Mladi za napredek Maribora</th></tr><tr><td>Vrsta šole:</td><td>Osnovna šola</td></tr><tr><td>Vrsta naloge:</td><td></td></tr><tr><td>Raz. podr.:</td><td>Fizika in astronomija</td></tr><tr><td>Šola:</td><td></td></tr><tr><td>Avtor:</td><td></td></tr><tr><td>Mentor:</td><td></td></tr><tr><td>Točke:</td><td></td></tr><tr><td>Mesto:</td><td></td></tr><tr><td>Priznanje:</td><td></td></tr><tr><td>Nagrada:</td><td>/</td></tr><tr><td colspan="2">Elektronski izvod: /</td></tr></table>'
import pandas
df = pandas.DataFrame(podatki)
_df = df
dedup_spaces = lambda s: " ".join(s.split())
df.Avtor = df.Avtor.apply(str.title)
df.Mentor = df.Mentor.apply(str.title)
# Y ther b doubl spacs smtims
df.Mentor = df.Mentor.apply(dedup_spaces)
def filtr(tip):
global df
if tip: df = _df[_df["Vrsta šole"] == tip]
else: df = _df
interact(filtr, tip=[None]+_df["Vrsta šole"].unique().tolist())
<function __main__.filtr(tip)>
df
Naslov naloge | Leto | Vrsta šole | Vrsta naloge | Raz. podr. | Šola | Avtor | Mentor | Točke | Mesto | Priznanje | Nagrada | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
39 | UGOTAVLJANJE PRISOTNOSTI UMETNIH BARVIL V JAJČ... | 2013 | Osnovna šola | Raziskovalna naloga | Biologija | OŠ KAMNICA | NEJC NOČ | MATEJA CERJAN | 155 | 1 | srebrno | prosta vstopnica |
40 | POENOSTAVLJEN MODEL SKAKANJA Z VRVJO | 2013 | Osnovna šola | Raziskovalna naloga | Fizika in astronomija | OŠ BRATOV POLANČIČEV | URBAN DUH | MLADEN TANCER | 153 | 1 | srebrno | nagrada SERŠ |
41 | ČIST ZRAK IN STAR AVTOMOBIL: ALI JE TO DOBRA K... | 2013 | Osnovna šola | Raziskovalna naloga | Geografija in geologija | OŠ DRAGA KOBALA | PATRICIJA MERKUŠ | HELENA ROŠKER ŠTOK | 104 | 1 | bronasto | / |
42 | VSE IMA SVOJO CENO. TUDI TI! (sociologija – zg... | 2013 | Osnovna šola | Raziskovalna naloga | Interdisciplinarno področje | OŠ TABOR I | HELENA PONUDIČ | ANJA ZATEZALO | 155 | 1 | srebrno | prosta vstopnica |
43 | VAROVANJE OSEBNE IDENTITETE PRI ANKETNEM RAZIS... | 2013 | Osnovna šola | Inovacijski predlog | Interdisciplinarno področje | OŠ FRANCA ROZMANA STANETA | LAURA MUZEK | JANKO MUZEK | 135 | 1 | bronasto | / |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
1600 | MUSLIMANKE IN STEREOTIPI | 2020 | Osnovna šola | Raziskovalna naloga | Sociologija | OŠ LUDVIKA PLIBERŠKA | TJAŠA MLAKER | NATAŠA COLJA | 123 | 5 | bronasto | / |
1601 | OREL NAD POTONOM SFINGINEGA LJUDSTVA | 2020 | Osnovna šola | Raziskovalna naloga | Zgodovina | OŠ FRANCETA PREŠERNA | GAJA GERMAVC PUŠNAR | MARTINA BORKO | 143 | 5 | srebrno | / |
1610 | MLADOSTNIKI: SREČNI ALI NESREČNI | 2020 | Osnovna šola | Raziskovalna naloga | Psihologija in pedagogika | OŠ PREŽIHOVEGA VORANCA | MAJA PAVLINIĆ | NATALIJA CARMONA | 134 | 6 | bronasto | / |
1616 | NOČNE MORE | 2020 | Osnovna šola | Raziskovalna naloga | Psihologija in pedagogika | OŠ LUDVIKA PLIBERŠKA | ANA KUPRIVEC | BRIGITA GODEC KOPČIČ | 133 | 7 | bronasto | / |
1623 | POMEN BARV | 2020 | Osnovna šola | Raziskovalna naloga | Psihologija in pedagogika | OŠ LUDVIKA PLIBERŠKA | LANA KOREN, TAJRA PETROVIČ | BRIGITA GODEC KOPČIČ | 121 | 8 | bronasto | / |
688 rows × 12 columns
šole = df.Šola.unique()
šole.sort()
print("\n".join(šole))
BIOTEHNIŠKA ŠOLA DIJAŠKI DOM DRAVA DIJAŠKI DOM LIZIKE JANČAR DOM ANTONA SKALE II. GIMNAZIJA III. GIMNAZIJA IZOBRAŽEVALNI CENTER PIRAMIDA MARIBOR OŠ ANGELA BESEDNJAKA OŠ BOJANA ILICHA OŠ BORCEV ZA SEVERNO MEJO OŠ BRATOV POLANČIČEV OŠ DRAGA KOBALA OŠ FRANCA ROZMANA STANETA OŠ FRANCETA PREŠERNA OŠ JANKA PADEŽNIKA OŠ KAMNICA OŠ LEONA ŠTUKLJA OŠ LUDVIKA PLIBERŠKA OŠ MAKSA DURJAVE OŠ MALEČNIK OŠ MARTINA KONŠAKA OŠ PREŽIHOVEGA VORANCA OŠ RADA ROBIČA LIMBUŠ OŠ SLAVE KLAVORE OŠ TABOR I OŠ TONETA ČUFARJA PROMETNA ŠOLA PRVA GIMNAZIJA SREDNJA EKONOMSKA ŠOLA SREDNJA ELEKTRO - RAČUNALNIŠKA ŠOLA SREDNJA GRADBENA ŠOLA IN GIMNAZIJA SREDNJA LESARSKA ŠOLA SREDNJA TRGOVSKA ŠOLA SREDNJA ZDRAVSTVENA IN KOZMETIČNA ŠOLA SREDNJA ŠOLA ZA GOSTINSTVO IN TURIZEM SREDNJA ŠOLA ZA OBLIKOVANJE TEHNIŠKI ŠOLSKI CENTER WALDORFSKA ŠOLA ŠKOFIJSKA GIMNAZIJA A. M. SLOMŠKA MARIBOR
for šn in ("II. GIMNAZIJA", "SREDNJA ELEKTRO - RAČUNALNIŠKA ŠOLA", ):
šola = df[df.Šola == šn]
print(f"{šola.Šola.iloc[0]}: \t Avg: {šola.Točke.mean()} \t({šola.Točke.sum()} točk z {šola.Točke.count()} nalogami)")
II. GIMNAZIJA: Avg: 152.57215189873418 (60266 točk z 395 nalogami) SREDNJA ELEKTRO - RAČUNALNIŠKA ŠOLA: Avg: 135.40816326530611 (26540 točk z 196 nalogami)
s = df.groupby("Šola").Točke.sum()
s.sort_values(ascending=False, inplace=True)
mask = s < s.sum()/100
s = s.loc[~mask]
from plotly.graph_objs import Pie
trace = Pie(labels=s.index, values=s.values, )
py.iplot([trace])
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(7,7))
ax.pie(s, labels=s.index)
plt.show()
mf = df[df.Avtor.map(str.lower).str.contains("miha frangež")]
mf
Naslov naloge | Leto | Vrsta šole | Vrsta naloge | Raz. podr. | Šola | Avtor | Mentor | Točke | Mesto | Priznanje | Nagrada | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
727 | SOCIALNI INŽENIRING NA SPLETU IN KAKO SE MU IZ... | 2016 | Srednja šola | Raziskovalna naloga | Računalništvo | SREDNJA ELEKTRO - RAČUNALNIŠKA ŠOLA | ANŽE MAVRIČ, MIHA FRANGEŽ | BRANKO POTISK | 140 | 2 | bronasto | / |
888 | KAKO BISTVENA JE LASTNIŠKA PROGRAMSKA OPREMA? | 2017 | Srednja šola | Raziskovalna naloga | Računalništvo | SREDNJA ELEKTRO - RAČUNALNIŠKA ŠOLA | MIHA FRANGEŽ, MIHA ŠIROVNIK | BRANKO POTISK | 131 | 1 | bronasto | / |
1096 | IP PREKO VSEGA | 2018 | Srednja šola | Raziskovalna naloga | Računalništvo | SREDNJA ELEKTRO - RAČUNALNIŠKA ŠOLA | PETER BERBERIH, MIHA FRANGEŽ | BRANKO POTISK | 145 | 1 | srebrno | prosta vstopnica |
1261 | SISTEM ZA PRIJAVO NA ŠPORTNE DNEVE IN OBVEZNE ... | 2019 | Srednja šola | Inovacijski predlog | Računalništvo | SREDNJA ELEKTRO - RAČUNALNIŠKA ŠOLA | MIHA FRANGEŽ | ALEŠ BEZJAK, BOJAN SKOK | 158 | 1 | srebrno | prosta vstopnica |
print(f"{mf.Točke.sum()} / {len(mf)}")
574 / 4
s = df.groupby("Šola").Točke.sum()
s.sort_values(ascending=False, inplace=True)
s
Šola II. GIMNAZIJA 60266 SREDNJA ELEKTRO - RAČUNALNIŠKA ŠOLA 26540 SREDNJA ŠOLA ZA OBLIKOVANJE 15132 PRVA GIMNAZIJA 10352 TEHNIŠKI ŠOLSKI CENTER 5171 SREDNJA LESARSKA ŠOLA 3451 SREDNJA GRADBENA ŠOLA IN GIMNAZIJA 3015 SREDNJA ŠOLA ZA GOSTINSTVO IN TURIZEM 2666 BIOTEHNIŠKA ŠOLA 2510 SREDNJA ZDRAVSTVENA IN KOZMETIČNA ŠOLA 1863 ŠKOFIJSKA GIMNAZIJA A. M. SLOMŠKA MARIBOR 1828 SREDNJA EKONOMSKA ŠOLA 1480 III. GIMNAZIJA 1479 IZOBRAŽEVALNI CENTER PIRAMIDA MARIBOR 594 DIJAŠKI DOM LIZIKE JANČAR 270 SREDNJA TRGOVSKA ŠOLA 266 DIJAŠKI DOM DRAVA 258 OŠ BOJANA ILICHA 157 PROMETNA ŠOLA 137 Name: Točke, dtype: int64
data = df[["Šola", "Leto", "Točke"]]
data
Šola | Leto | Točke | |
---|---|---|---|
0 | II. GIMNAZIJA | 2013 | 170 |
1 | II. GIMNAZIJA | 2013 | 170 |
2 | II. GIMNAZIJA | 2013 | 170 |
3 | TEHNIŠKI ŠOLSKI CENTER | 2013 | 164 |
4 | II. GIMNAZIJA | 2013 | 166 |
... | ... | ... | ... |
1622 | III. GIMNAZIJA | 2020 | 127 |
1624 | SREDNJA ELEKTRO - RAČUNALNIŠKA ŠOLA | 2020 | 68 |
1625 | DIJAŠKI DOM DRAVA | 2020 | 115 |
1626 | SREDNJA ELEKTRO - RAČUNALNIŠKA ŠOLA | 2020 | 144 |
1627 | II. GIMNAZIJA | 2020 | 130 |
940 rows × 3 columns
število = pandas.crosstab(data.Leto, data.Šola, values=data.Točke, aggfunc=len)
število
Šola | BIOTEHNIŠKA ŠOLA | DIJAŠKI DOM DRAVA | DIJAŠKI DOM LIZIKE JANČAR | II. GIMNAZIJA | III. GIMNAZIJA | IZOBRAŽEVALNI CENTER PIRAMIDA MARIBOR | OŠ BOJANA ILICHA | PROMETNA ŠOLA | PRVA GIMNAZIJA | SREDNJA EKONOMSKA ŠOLA | SREDNJA ELEKTRO - RAČUNALNIŠKA ŠOLA | SREDNJA GRADBENA ŠOLA IN GIMNAZIJA | SREDNJA LESARSKA ŠOLA | SREDNJA TRGOVSKA ŠOLA | SREDNJA ZDRAVSTVENA IN KOZMETIČNA ŠOLA | SREDNJA ŠOLA ZA GOSTINSTVO IN TURIZEM | SREDNJA ŠOLA ZA OBLIKOVANJE | TEHNIŠKI ŠOLSKI CENTER | ŠKOFIJSKA GIMNAZIJA A. M. SLOMŠKA MARIBOR |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Leto | |||||||||||||||||||
2013 | 1.0 | NaN | 1.0 | 55.0 | 1.0 | NaN | NaN | NaN | 9.0 | 3.0 | 12.0 | 6.0 | NaN | 2.0 | 2.0 | 5.0 | 16.0 | 9.0 | 1.0 |
2014 | 2.0 | NaN | 1.0 | 31.0 | 1.0 | NaN | 1.0 | NaN | 8.0 | 3.0 | 18.0 | 3.0 | 4.0 | NaN | 2.0 | 3.0 | 13.0 | 5.0 | NaN |
2015 | 3.0 | 1.0 | NaN | 66.0 | NaN | NaN | NaN | NaN | 9.0 | 1.0 | 16.0 | 2.0 | 4.0 | NaN | 2.0 | 4.0 | 12.0 | 4.0 | 2.0 |
2016 | 4.0 | NaN | NaN | 57.0 | NaN | NaN | NaN | NaN | 8.0 | NaN | 23.0 | 5.0 | 2.0 | NaN | 1.0 | 1.0 | 17.0 | 4.0 | 5.0 |
2017 | 2.0 | NaN | NaN | 57.0 | NaN | NaN | NaN | NaN | 7.0 | 1.0 | 35.0 | 1.0 | 3.0 | NaN | 3.0 | 2.0 | 13.0 | 6.0 | 1.0 |
2018 | 1.0 | NaN | NaN | 36.0 | NaN | 1.0 | NaN | NaN | 8.0 | NaN | 24.0 | 4.0 | NaN | NaN | 1.0 | 1.0 | 8.0 | 3.0 | 1.0 |
2019 | 2.0 | NaN | NaN | 46.0 | 6.0 | 2.0 | NaN | NaN | 9.0 | 1.0 | 33.0 | 1.0 | 5.0 | NaN | 2.0 | 3.0 | 18.0 | 2.0 | 1.0 |
2020 | 3.0 | 1.0 | NaN | 47.0 | 3.0 | 1.0 | NaN | 1.0 | 10.0 | 1.0 | 35.0 | NaN | 4.0 | NaN | NaN | NaN | 10.0 | 2.0 | 1.0 |
fig, ax = plt.subplots(figsize=(9,12))
število.plot(kind="bar", stacked=True, ax=ax)
plt.legend(bbox_to_anchor=(1.57,1.01), loc="upper right")
plt.show()
vsote = pandas.crosstab(data.Leto, data.Šola, values=data.Točke, aggfunc=sum)
vsote
Šola | BIOTEHNIŠKA ŠOLA | DIJAŠKI DOM DRAVA | DIJAŠKI DOM LIZIKE JANČAR | II. GIMNAZIJA | III. GIMNAZIJA | IZOBRAŽEVALNI CENTER PIRAMIDA MARIBOR | OŠ BOJANA ILICHA | PROMETNA ŠOLA | PRVA GIMNAZIJA | SREDNJA EKONOMSKA ŠOLA | SREDNJA ELEKTRO - RAČUNALNIŠKA ŠOLA | SREDNJA GRADBENA ŠOLA IN GIMNAZIJA | SREDNJA LESARSKA ŠOLA | SREDNJA TRGOVSKA ŠOLA | SREDNJA ZDRAVSTVENA IN KOZMETIČNA ŠOLA | SREDNJA ŠOLA ZA GOSTINSTVO IN TURIZEM | SREDNJA ŠOLA ZA OBLIKOVANJE | TEHNIŠKI ŠOLSKI CENTER | ŠKOFIJSKA GIMNAZIJA A. M. SLOMŠKA MARIBOR |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Leto | |||||||||||||||||||
2013 | 142.0 | NaN | 136.0 | 8260.0 | 145.0 | NaN | NaN | NaN | 1299.0 | 426.0 | 1746.0 | 792.0 | NaN | 266.0 | 297.0 | 656.0 | 2125.0 | 1348.0 | 94.0 |
2014 | 306.0 | NaN | 134.0 | 4682.0 | 135.0 | NaN | 157.0 | NaN | 1172.0 | 446.0 | 2560.0 | 318.0 | 597.0 | NaN | 296.0 | 422.0 | 1885.0 | 721.0 | NaN |
2015 | 456.0 | 143.0 | NaN | 9836.0 | NaN | NaN | NaN | NaN | 1367.0 | 141.0 | 2104.0 | 284.0 | 634.0 | NaN | 264.0 | 568.0 | 1721.0 | 632.0 | 331.0 |
2016 | 505.0 | NaN | NaN | 8771.0 | NaN | NaN | NaN | NaN | 1258.0 | NaN | 3229.0 | 746.0 | 298.0 | NaN | 145.0 | 153.0 | 2260.0 | 587.0 | 753.0 |
2017 | 308.0 | NaN | NaN | 8761.0 | NaN | NaN | NaN | NaN | 1100.0 | 158.0 | 4551.0 | 143.0 | 486.0 | NaN | 445.0 | 272.0 | 1893.0 | 843.0 | 164.0 |
2018 | 85.0 | NaN | NaN | 5619.0 | NaN | 147.0 | NaN | NaN | 1259.0 | NaN | 3336.0 | 563.0 | NaN | NaN | 145.0 | 149.0 | 1145.0 | 459.0 | 167.0 |
2019 | 263.0 | NaN | NaN | 7109.0 | 798.0 | 298.0 | NaN | NaN | 1327.0 | 146.0 | 4413.0 | 169.0 | 784.0 | NaN | 271.0 | 446.0 | 2623.0 | 317.0 | 161.0 |
2020 | 445.0 | 115.0 | NaN | 7228.0 | 401.0 | 149.0 | NaN | 137.0 | 1570.0 | 163.0 | 4601.0 | NaN | 652.0 | NaN | NaN | NaN | 1480.0 | 264.0 | 158.0 |
list(vsote.index)
['2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020']
list(vsote[vsote.keys()[0]])
[142.0, 306.0, 456.0, 505.0, 308.0, 85.0, 263.0, 445.0]
import plotly.graph_objs as go
keys = vsote.sum().sort_values(ascending=False).keys()
fig = go.Figure([go.Bar(x=vsote.index, y=vsote[šola], name=šola) for šola in keys])
fig.update_layout(barmode='stack', height=900)
fig.show()
fig, ax = plt.subplots(figsize=(9,12))
vsote.plot(ax=ax)
plt.legend(bbox_to_anchor=(1.57,1.01), loc="upper right")
plt.show()
def graf(bins):
for year in df.Leto.unique():
df[df.Leto == year].Točke.plot(kind="hist", bins=bins)
interact(graf, bins=(5,150,5))
<function __main__.graf(bins)>
šl = df[["Šola", "Leto", "Točke"]]
šl = šl.groupby(["Leto"])
šl = šl.sum()
šl
Točke | |
---|---|
Leto | |
2013 | 17732 |
2014 | 13831 |
2015 | 18481 |
2016 | 18705 |
2017 | 19124 |
2018 | 13074 |
2019 | 19125 |
2020 | 17363 |
fig, ax = plt.subplots(figsize=(12,6))
šl.Točke.plot(kind="bar", x="Leto", y="Točke", ax=ax, legend=True)
plt.show()