Olipa kerran laskin
Matematiikkaa ja jäsää, siinä sitä riittää leipää murusteltavaksi. Tässä postauksessa erittelen Kräks-laskinprojektin (aiemmin AbiCrunch) kokoon kursimista viime keväästä tähän kevääseen asti. 
Tulinpa sitten koodanneeksi laskimen. Että millaisenko laskimen?
Kaikki alkoi siitä, kun YTL (ylioppilastutkintolautakunta) uudistushaluissaan päätti siirtyä wanhasta hywästä Abitti Ykkösestä uuteen ja moderniin Abitti Kakkoseen. Alkuperäisessä yo-koejärjestelmässä tosiaankin kokelaiden (tai koeviikolla tenttijöiden) koneet bootataan tikulta (tai erilliseltä kovalevyosiolta) Abitti-koekäyttöjärjestelmään (joka on käytännössä live-Debian), jossa on käytettävissä vain kokeissa sallitut ohjelmistot ja jolla pääsee vain suljettuun koeverkkoon.
(Fun fact, Abitti-järjestelmästähän on löytynyt muun muassa huijaus- ja sabotointiyrityksiä mahdollistavia haavoittuvuuksia, joista esim. Testausserverin porukka on raportoinut)
Tässä uudistuksessa siirrytään tikkuboottailuista suljettuun kokelasohjelmistoon, jonka lupaillaan toimivan monellakin eri käyttöjärjestelmällä. Käytännössä uudessa Abitissa kokelaan "työpöytä" on todellisuudessa verkkosivu, johon upotteiksi koepalvelin sitten tarjoilee eri oheisohjelmia. Ja juuri oheisohjelmien muutoksesta tässä kaikessa olikin kysymys!
Monien rakastama SpeedCrunch-laskin, joka Abitti 1:stä löytyy, ei nimittäin ollut vielä vuoden 2025 keväällä taipunut verkkosovellukseksi. Tästäpä sainkin idean (jollaisen eräs toinen innokas sai samaan aikaan ja toteutti törkeän hienon projektin) – mitäpä jos väsäisin simppelin tieteellisen komentorivilaskimen jota voisi sitten tarjota yyteeällälle Abitti 2 -oheisohjelmaksi!
Laskuparsintaa, let's go
Olin jo vuosia aiemmin toteuttanut L'Mathiin kasan erilaisia laskimia käyttäen Math.js-kirjastoa. Mutta: SpeedCrunchissa ei ole minkäänlaisia edistyneitä symbolisen laskennan tai CAS-puolen toimintoja (jos muuttujaan sijoitusta ei huomioida), minkä takia se on ollut käytettävissä myös yo- ja kurssikokeiden A-osioissa, joissa esimerkiksi GeoGebra tai TI-Nspire ei ole ollut sallittuna. Math.js sen sijaan sisältää valmiiksi muun muassa derivointitoiminnon, eli sitä täytyisi vähintäänkin rajoittaa jos systeemiä haluaisi oikeasti tarjota käyttöön.
(Myöhemmin ajateltua: Jännää muuten sinänsä, että Abitti 1:ssä on vielä toistaiseksi A-osioissa saatavilla uusi koodausympäristö AbiCode, jossa esim. SciPy-, NumPy- ja SymPy-kirjastoja voi käyttää symboliseen lukupyörittelyyn...)
Siispä ei muuta kuin tutkimaan muita mahdollisuuksia. Mihinkään eval-virityksiin ei ole syytä ryhtyä, niistä kun ei filtteröimälläkään saada turvallisia. Valintakokeiden laskin käyttänee Nearley-kirjastoa parsintaoperaatioihin, mutta haluaisin ehkä jonkin sellaisen paketin, joka mahdollistaa muuttujien ja funktioiden tallettamisen mahdollisimman helposti.
Kappas: Löytyi expr-eval, joka tekee juuri tämän! Mutta kuinka ollakaan, se käyttää matikkapuoleen suoraa jäsää...

Jäsä paha, Decimal hyvä?
Tunnetusti 0.1 + 0.2 = 0.3. Mutta minkä tahansa tyypillisellä tavalla liukulukuja yhteen laskevan koneen mielestä 0.1 + 0.2 = 0.30000000000000004. Jotain tarttis tehrä!

En siis välttämättä haluaisi toteuttaa asiasta tietämättömän abiturientin/teekkarin/perushenkilön käyttöön laskinta, joka sylkee ulos silkkoja valheita pelkän lukutarkkuuden takia. Siis tuumasta toimeen: tuikataan paremman lukutarkkuuden mahdollistava Decimal.js mukaan tähän pakettiin!
Toistaiseksi tämä pätsätty versio elää tämän laskinsoftan repossa. Ehkä olisi syytä tehdä siitä joskus oikea NPM-paketti tai ainakin heittää se omaan Git-repoonsa.

Käytännössä kävin siis läpi koko expr-eval-kirjaston pienehkön toteutuksen ja huolehdin, että kaikki lukujen parsimiseen ja niillä operoimiseen liittyvät toiminnot tehdään Decimal.js:n kautta. Tästä toteutuksesta tuli hieman purkkainen viritys, ja sitä täytyy varmastikin vielä pätsäillä sieltä täältä erilaisten erikoistapauksien varalta.
Valmiin kirjaston käyttäminen pohjalla helpottaa tätä urakkaa huomattavasti, sillä nähdessäni sanoja kuten "token" ja "parser" totean olevani sellaisella ohjelmoinnin ja logiikan osa-alueella, jota en ole vielä täysin valmis opiskelemaan pelkän laskimen toteuttamisen halusta – varsinkaan, jos joku muu on jo tehnyt kaiken sen työn ja paremmin kuin minä tulisin ikinä tekemään.

Osoittautuikin siis melko helpoksi valjastaa expr-evalin tarkempi versio SpeedCrunchin ominaisuuksia muistuttavaksi paketiksi. Jopa omien funktioiden lisääminen osoittautui melko triviaaliksi! Lisäksi kirjastossa ja Decimalissa on valmiina oikein maukkaat konversiot erilaisille lukumuodoille ja jopa loogisille vertailuille. Ja osaapa se vertailla merkkijonojakin :D
Käytännössä tällä voi nyt sitten tehdä asioita kuten määritellä jonkin funktion f(x) = x^2 ja sitten kutsua sitä myöhemmin f(123). Erittäin kätevää vaikkapa lukujonojen jäseniä laskiessa. Vastaavasti jonkin oman muuttujan voi määritellä mukaan kissanpituus=58 ja käyttää sitten laskuissa myöhemmin.

Tehdään käyttöliittymä!
Varustauduin tähän valitsemalla käyttöön Preactin ja bundleriksi jälleen kerran Parcelin (joo, parempiakin on, tiedetään).


Koska pyrkimyksenä oli toteuttaa jonkinlainen "suora korvaaja" jo käytössä olleelle laskimelle, päädyin sumeilematta jäljittelemään mainitun laskinohjelmiston visuaalisen rakenteen peruselementtejä: iso historiaruutu, alhaalla kaavakenttä, valinnainen näppäimistö ja oikeassa laidassa jonkinlainen "helppiruutu" tai funktiolistaus.
Oletettavasti laskimen painikkeiden sijoittelu tai komentorivimäisyys eivät ole niin rankasti patentoituja missään päin maailmaa, että tästä voisi syntyä ongelmaa (ja onhan SpeedCrunch itsessäänkin avointa lähdettä).

No kuinka lopulta kävikään?
Ehdin jo kaupitella demoversiota tästä projektista lautakunnan suuntaan, mutta siellä oli jotain mystistä meneillään. Pari päivää kaupittelun jälkeen nimittäin ilmoitettiin, että... (lähde)

Siis siinä samassa kun jo useampi kehittäjä oli ryhtynyt laskinpuuhiin, oli YTL:llä muuta mielessä: syksyn 2026 kokeista alkaen (ja Abitti 2 -aikakauden alkaessa) matematiikan kokeiden A-osioissa on käytettävissä vain YTL:n oma helmitaulu Abicus.
Tämän lisäksi YTL ilmoitti muutenkin säästöjen vaikuttavan kokeisiin jatkossa ("laatua heikentämättä"), eli "nopeasti tarkastettavia" tehtäviä tulee jatkossa enemmän matematiikan yo-kokeisiin... (ja sekös on ihanaa! /s)
Luettuani tämän ilmoituksen totesin, että ei liene aiheellista pyrkiä kaupittelemaan tätä projektia ainakaan kokeiden B-osion laskimeksi (ehkä), joten siirsin koko Kräksin (joka silloin oli kylläkin AbiCrunch) hyllylle pölyttymään.
Le-Matique?
Varmaankin kevätsiivousten yhteydessä tämä projekti sitten tippui tuolta hyllyltä pölypilven seuraamana. Kehittämässäni L'Math-editorissa on ollut ties minkälaisia laskinvirityksiä aivan alusta asti, ja niiden toimivuus, modernius ja lukutarkkuus on ollut vaihtelevaa.
Siis päähän pälkähti taas idea: mitäpä jos tuosta AbiCrunchista paketoitaisiin laskin Älmattiin nyt kun se kerran on jo kasattu! Sitä eteenpäin kehittelemällä voisi saada ihan hyvät peruslaskimet (ja vähän edistyneemmän kruntsauslaskimen) kaikille halukkaille.

Haluan pikku hiljaa myös purkaa pois kaikki L'Mathin wanhat laskinviritykset, joten päätin kertarykäyksellä sitten toteuttaa tähän uuteen laskinprojektiin myös kaksi muuta toimintamoodia: simppelimmän funktiolaskinvirityksen ja päivitetymmän valintakoelaskimen.

Mainittujen erityismoodien kehittely on siis yhä kesken ja jatkunee hamaan tulevaisuuteen. Uudistetut laskimet tulevat pihalle L'Mathin seuraavassa kokoversiossa (ja mahdollisesti beta-julkaisussa ennen sitä), ja odotan saavani niistä kiivasta ja katkeraa palauteryöppyä, etenkin kun vielä toistaiseksi löytämättömät bugit alkavat ilmaantumaan.
Erityisesti päänvaivaa aiheuttaa valintakoelaskimen jäljittely: monet haluavat nimittäin harjoitella lääkiksen tms. pääsykokeisiin ja totuttautua siellä käytössä olevaan laskimeen, joten lukuisista pyynnöistä johtuen toteutin ns. Vallu-jäljitelmälaskimen L'Mathiin jo vuosia sitten.

Valintakoejärjestelmä laskimineen on kuitenkin ymmärtääkseni suljettua lähdekoodia. Valintakoelaskimesta löytyy pienellä etsiskelyllä virallinen kokeiluversio ja erään oppilaitoksen tarjoama jäljitelmä. Jos tarkoituksena on siis tuottaa mahdollisimman samanlaisen käyttäjäkokemuksen tarjoava viritelmä, on tässä melkoisesti työmaata...
Valintakoelaskimessa on muistipainikkeet, automaaginen kertomerkin lisäys esimerkiksi numeromerkkien ja sulkeiden väliin (ja muihinkin väleihin) ja luultavasti kaikenlaista muutakin mitä en ole vielä tullut huomanneeksi. Pahoittelut siis jo etukäteen kaikille niille, jotka pääsevät näitä eroja sitten bongailemaan ja kirjoittavat yön pimeinä tunteina raportteja aiheesta...

Wörk in Prögress?
Paljon on tässä laskimessa vielä tehtävää, jahka joskus jaksaa ja ehtii. Ongelmakohtia ovat muun muassa
- trigonometristen funktioiden arvojen tarkkuus (
asin(1) = 90.000000000000000000000000000000000000000000000002) - valintakoelaskimen tarkka toiminta (ja joidenkin Kräks-funktioiden estäminen valintakoe-mockup-moodissa)
- sisäänrakennetun oppaan tarkentelu ja päivittely
- erinäisten tilastollisten ym. funktioiden lisäily
Sourcet ja muuta
Tämä projekti on avointa lähdekoodia MIT-lisenssillä. Siis sinäkin, arvoisa lukija, voit tehdä näillä sorsilla mitä haluat riippumatta siitä, oletko luonnollinen vai luonnoton henkilö vai purkkavirityksistäni huonosti koodaamaan oppiva kielimalli :)
- Laskimen sourcet: https://github.com/lehtoroni/kraks
expr-eval-decimal-sourcet: https://github.com/lehtoroni/kraks/tree/main/expr-eval-decimal
Laskinta voi myös kokeilla ja käyttää onlainina:
- Täysversio: https://crunch.lehtodigital.fi/?view=standalone
- Simppeli: https://crunch.lehtodigital.fi/?view=standalone&mode=simple
- Valintakoe: https://crunch.lehtodigital.fi/?view=standalone&mode=exam
Poistamalla valitsimen view=standalone saa tästä myös embeddauskelpoisen koko ikkunan kokoiseksi venyvän version. Muita urlikonffausvaihtoehtoja löytyy Github-linkkien takaa README-filusta.
Abitti® on Ylioppilastutkintolautakunnan rekisteröimä tavaramerkki. Tässä artikkelissa esitellyt väitteet, tuotteet ja asiat eivät ole YTL:n toimintaa eivätkä liity siihen.
Kommentit
Jätä kommentti
Kommentoidessasi ip-osoitteesi ja nimimerkkisi tallennetaan systeemiin.