MVnet logo

Tutkielmat » Yliopisto » Java-ohjelmoinnin projektityö

  • Julkaistu: 08.03.2008
  • Päivitetty: 14.02.2011
  • Kommentit
Java-ohjelmointikurssin laajahko projektityö: Opintoapuri-ohjelma
Tehty: 01.12.2006 Arvosana: 5/5
Sivuja: 22 kpl Sanamäärä: 6400
Tekijä: Mikko Vestola

Sisällys

Java-ohjelmoinnin projektityö: Opintoapuri

Tällä sivulla esitetty ohjelmoinnin projektityö oli osa Teknillisen korkeakoulun kurssin T-106.1240 - Ohjelmoinnin jatkokurssi T1 suorittamista. Projektityö tehtiin itsenäisesti ja kurssin arvosana muodostui kokonaisuudessaan tästä projektityöstä. Ohjelmointikielenä käytettiin Javaa. Projektityön ohjeet pitäisivät löytyä edelleenkin kurssin vuoden 2006 kotisivuilta, jos kyseisiä sivuja ei ole vielä poistettu. Projektityön tarkoitus oli seuraava (lainaus kurssin kotisivuilta):

Projektityö on yksilötyönä tehtävä, harjoitustehtäviä laajempi ohjelmointiprojekti, jonka tarkoituksena on antaa opiskelijalle kokemusta suuremman ohjelmakokonaisuuden suunnittelemisesta, toteutuksesta, testaamisesta ja dokumentoinnista. Projektityö lienee kurssin vaativin, mutta myös palkitsevin osuus, joka vie paljon aikaa ja vaivaa. Niinpä siihen on syytä paneutua huolella heti suunnitteluvaiheesta alkaen.

Projektityön aiheen sai valita itse ennalta määrätyistä aiheista. Aiheissa oli annettu karkeahkot kuvaukset, minkä tyyppinen projektissa laadittavan ohjelman tulee olla. Aiheet sisälsivät useita eri vaikeusasteita, joista opiskelija sai tähdätä itselleen sopivimpaan. Aihekuvauksessa oli tällöin kerrottu, millaisia ominaisuuksia ohjelmaan tulee toteuttaa, jotta se täyttäisi tietyn vaativuusasteen kriteerit. Vaikeusasteita oli kolme ja niiden arvosteluskaala oli seuraava (maksimi arvosana on 5):

Projektityön arvosanan määräytyminen
Vaikeusaste Oletusarvosana Arvosteluasteikko
Helppo 2 0-3
Keskivaikea 3 0-4
Vaativa 4 0-5

Taulukossa mainitun oletusarvosanan sai "keskitasoisesti" tehdystä työstä, ja oletusarvosanasta poikettiin, kun työssä oli erityisiä ansioita tai puutteita. Projektityöstä laadittiin ennen varsinaista toteuttamista yleissuunnitelma ja tekninen suunnitelma, joissa esitettiin projektin toteutus pääpiirteissään. Hyvästä suunnitelmasta sai plussan arvosanaan, joka rajatapauksessa nosti arvosanaa yhdellä.

Itse valitsin aiheen Opintojen suunnittelija, jonka tehtäväkuvaus pitäisi löytyä kurssin vanhoilta kotisivuilta. Lyhykäisyydessään kyseessä on siis ohjelma, joka auttaa opiskelijaa opintosuunnitelman teossa, pitäen huolen esim. siitä että kaikki pakolliset kurssit tulevat opintosuunnitelmaan ja että kurssit suoritetaan oikeassa järjestyksessä.

Projektisuunnitelman yleissuunnitelma

1. Henkilötiedot

  • Aihe: 306, Opintojen suunnittelija
  • Nimi: Mikko Vestola
  • Päiväys: 06.10.2006

2. Yleiskuvaus

Tarkoituksena on tehdä sovellus, joka toimii opiskelijan henkilökohtaisena apuvälineenä opintojen suunnitteluun. Kun opiskelija on syöttänyt kurssit, jotka hän aikoo suorittaa, ohjelma luo käyttäjälle opintosuunnitelman, jota opiskelija voi jälkeenpäin vielä muokata. Opintosuunnitelmaa noudattamalla kurssit tulee saada suoritettua mielekkäässä järjestyksessä ja kohtuullisessa ajassa.

Tarkoituksena on tehdä vaatimustasoltaan keskivaativa versio (a). Myös joitain vaativan vaikeustason (a+b) toimintoja saatetaan toteuttaa, mikäli innostusta, osaamista ja aikaa löytyy. Ohjelma tehdään siten, että se sopii yhteen nykyisen tutkintorakenteen kanssa. Eli syys- ja kevätlukukausien tilalle tulevat neljä periodia.

Opintosuunnitelma on tarkoitus esittää myös graafisesti pylväsesityksenä. Pylväsesityksessä näkyisi, kuinka paljon opintoja (=opintopisteitä) on valittu kullekin periodille. Jos jollekin periodille on valittu vähän kursseja, näkee pylväsesityksestä heti, että kyseiseen periodiin kannattaisi valita lisää kursseja.

3. Käyttöliittymän luonnos

Käyttöliittymän alustava versio

Käyttöliittymän alustava versio (tehty Eclipsen Visual Editorilla)

Käyttöliittymästä tehdään graafinen. Käyttöliittymän ikkuna on jaettu välilehtiin: Henkilötiedot, Kurssit, Opintosuunnitelma ja Hallinta.

Henkilötiedot välilehdellä syötetään opiskelijan tiedot (nimi, koulutusohjelma, opiskelijanumero, valittu pääaine ja sivuaine jne.).

Kurssit-välilehdellä näytetään listaukset saatavilla olevista kursseista koulutusohjelmittain joko kaikki koulutusohjelman kurssit kerralla tai sitten kurssit rakenteittain (pääaine, sivuaine jne...). Listasta voi valita kursseja lisättäväksi opintosuunnitelmaan. Pakolliset kurssit ja opintosuunnitelmassa jo olevat kurssit näytetään korostetusti. Välilehti on vielä jaettu kahtia, jossa vasemmalla puolella näkyy kurssilistaus ja oikealla puolella näkyy kurssilistauksesta valitun kurssin tarkemmat tiedot (nimi, kurssikoodi, kuvaus, www-sivu tms.)

Opintosuunnitelma-välilehdellä opintosuunnitelmaa voi tarkastella periodeittain tai opintokokonaisuuksittain (perusopinnot, pääaine, vapaavalintaiset opinnot jne...). Opintosuunnitelmasta voi poistaa kursseja tai siirtää niitä toiselle periodille.

Hallinta-välilehdellä voi järjestelmään lisätä uusia kursseja. Kun kurssia lisätään, kysytään siitä mm. seuraavia tietoja: nimi, kurssikoodi ja mihin koulutusohjelmaan kurssi kuuluu. Täältä voi myös luoda uuden koulutusohjelman, jolle voi luoda pää- tai sivuaineita sekä määritellä, mitkä kurssit kuuluvat koulutusohjelman perusopintoihin jne.

Ikkunan yläosan valikoista voi tallentaa/ladata kurssilistauksen ja opintosuunnitelman myöhempää käyttöä varten.

Kaikki muutokset tehdään graafisesti klikkailemalla painikkeita, valitsemalla valintanappeja tai syöttämällä tekstiä tekstikenttiin jne. Käyttäjän aiheuttamien toimintojen tulosteet näytetään ikkunan alaosassa.

4. Tiedostot ja tiedostoformaatit

Tiedot kursseista, opiskelijan tiedoista ja opintosuunnitelmasta tallennetaan ns. perus tekstimuotoisina tiedostoina. Näin tiedostoja on helppo muokata käsin ja niiden parsiminen on silti melko yksinkertaista. Mielestäni on tärkeää, että esimerkiksi kursseja on helppo editoida/lisätä suoraan tekstitiedostoon (sovelluksen graafinen käyttöliittymä kun ei ole välttämättä se nopein tapa lisätä kursseja). Esimerkiksi tiedot kursseista tallennettaisiin tyyliin:

#==KOULUTUSOHJELMAN KURSSIT==#

#==KURSSI==#

#Nimi
Ohjelmoinnin peruskurssi T
#Koodi
T-106.1220
#Kuvaus
Java-ohjelmoinnin alkeet. 
Kurssilla opitaan ohjelmoinnin perusteet Java-ohjelmointikielellä. 
Kurssiarvosana koostuu tentistä ja harjoitustehtävistä.
#Esitiedot
T-0.1001 
#Op
6
#Periodi
1

#==KURSSI==#

#Nimi
Ohjelmoinnin jatkokurssi T1
#Koodi
T-106.1240
#Kuvaus
Tämä kurssi on jatkoa edelliselle ohjelmoinnin jatkokurssille. 
Kurssilla on tarkoitus oppi lisää ohjelmoinnista. 
Kurssilla tehdään projektityö. Tenttiä ei ole.
#Esitiedot
T-106.1200 
T-106.1220
#Op
5
#Periodi
1

5. Järjestelmätestaussuunnitelma

Testaamista varten olisi hyvä rakentaa jo jonkinlainen toimiva luonnos käyttöliittymästä, jolloin testaaminen helpottuisi. Testaus kannattaa aloittaa testaamalla kurssien lisäystä. Saman kurssikoodin omaavia kursseja ei sallita. Kun kursseja syöttää, täytyy ne syöttää oikeassa järjestyksessä (eli perusopinnot ensin, sitten vaativammat opinnot, joilla on esitietovaatimuksia). Näin, koska kursseista on esitietovaatimusten takia viittauksia aiempiin kursseihin. Kun kurssille annetaan esitietovaatimuksia, ei voi olla sellaista tapausta, jossa kurssin A esitietovaatimuksena on kurssi B, jolla on esitietovaatimuksena kurssi A (tällöin kurssit olisivat mahdoton suorittaa).

Kun kursseja on lisätty sovellukseen, testataan niiden tietojen tallentamista tiedostoon ja lukemista tiedostosta. Testaaminen helpottuu, kun ei tarvitse joka testikerralla lisätä uusia kursseja.

Kun opintosuunnitelmasta siirtää kurssin jollekin periodille, pitää tarkastaa, että kurssi myös järjestetään kyseisellä periodilla. Jos ei järjestetä, ei siirtoa sallita. Myös esitietovaatimukset tarkastetaan. Jos kurssin esitiedoissa esiintyviä kursseja ei ole suunniteltu suoritettavan aikaisemmilla periodeilla, ei siirtoa periodille hyväksytä.

Jos kurssi siirretään johonkin muuhun opintoihin (esim. pääaineen opintoihin), tarkastetaan, että kyseinen kurssi voidaan siihen sisällyttää. Kursseja poistettaessa opintosuunnitelmasta tarkastetaan, että pakollisia opintoja ei poisteta.

Projektisuunnitelman tekninen suunnitelma

1. Ohjelman rakennesuunnitelma

Ohjelma on jaoteltu seuraaviin luokkiin:

  • Koulutusohjelma
  • Kurssi
  • Opinto
  • Opintosuunnitelma
  • Suoritus
  • Tallentaja
  • Lataaja
  • GUI

Alla jonkinmoinen UML-luonnos luokkarakenteesta:

UML-kaavion luonnos

UML-kaavion luonnos

Luokkajako on tehty ajatellen reaalimaailmaa TKK:ssa. Jokin koulutusohjelma tarjoaa kursseja ja opintoja (perusopinnot, pääaineita, sivuaineita jne.), jotka koostuvat kursseista. Opiskelijan opintosuunnitelma taas koostuu suorituksista, jotka ovat kursseja suoritettuna tiettynä aikana (tai suunniteltu suoritettavan). Suoritukset kuuluvat johonkin opintoon (esim. perusopintoihin), joka kuuluu opiskelijan koulutusohjelman opintoihin.

Koulutusohjelma-luokka mallintaa eri koulutusohjelmia. Koulutusohjelmat tarjoavat kursseja ja opintoja. Koulutusohjelmalla on siis lista kursseista ja opinnoista, joita se voi tarjota. Keskeisiä metodeja ovat seuraavat: listaa kurssit järjestyksessä kurssikoodeittain, listaa kurssit opintokokonaisuuksittain (pääaineet, perusopinnot jne.), lisää kurssi koulutusohjelmaan, poista kurssi ja etsi kurssi, joka palauttaa etsittävän kurssikoodin omaavan olion.

Kurssi-luokka mallintaa nimensä mukaisesti kursseja. Kurssilla on nimi, kurssikoodi, opintopistemäärä, periodi, jolloin se järjestetään, kuvaus ja lista kurssikoodeista, jotka ovat kurssin esitietoina. Lisäksi kurssilla on tieto siitä, järjestetäänkö kurssia enää vai ei. Jos kurssi poistetaan tarjolla olevista kursseista, ei tietoja kurssista poisteta, vaan kurssiin lisätään tieto, että kurssia ei enää järjestetä. Näin he, jotka ovat suorittaneet jo kyseisen kurssin voivat yhä tarkastella kurssin tietoja. Kurssi-luokan keskeisiä metodeita ovat normaalien saantimetodien (kerroNimi, kerroKurssikoodi jne...) lisäksi metodi, joka lisää kurssin esitietovaatimusten listaan halutun kurssikoodin.

Opinto-luokka kuvaa koulutusohjelman opintoja (perusopinnot, pääaineen opinnot, suunnan opinnot jne.). Opinnolla on aina nimi (esim. "Tietojenkäsittelyteorian pääaine"), tyyppi (perusopintoja, pääaine, sivuaine jne.), laajuus opintopisteinä sekä listat opintoon kuuluvista pakollisista ja vapaavalintaista kursseista. Opinto-luokan keskeisiä metodeja ovat: lisää kurssi opintoon (tarkastaa, ettei kurssia ole jo opinnossa), tarkasta onko parametrina annettu kurssi pakollinen (eli onko pakollisten kurssien listassa) ja kuuluuko parametrina annettu kurssi opintoon.

Opintosuunnitelma-luokka kuvaa opiskelijan opintosuunnitelmaa. Opintosuunnitelmassa on tallennettuna, kenelle opiskelijalle suunnitelma kuuluu (nimi ja opiskelijanumero), sekä valitut pää- ja sivuaineet sekä suunta. Suunnitelmassa on myös listattu kaikki ne suoritukset, jotka opiskelija on valinnut suoritettavakseen. Keskeisiä metodeja ovat suoritusten listaaminen periodeittain/opintokokonaisuuksittain, ja kurssin lisääminen opintosuunnitelmaan.

Suoritus-luokka kuvaa opiskelijan valitseman kurssin suoritusta. Suoritus koostuu kurssista sekä periodista ja lukuvuodesta, jolloin kurssi on ajateltu suorittaa. Suoritus kuuluu lisäksi johonkin opintoon (tai jos ei kuulu, se tulkitaan kuuluvan vapaavalintaisiin opintoihin). Lisäksi suoritukseen on tallennettu tieto, onko suoritus jo suoritettu. Keskeisiä metodeja ovat: siirto toiselle periodille, siirto toiseen opintoon ja esitietokurssien tarkastus (että on suoritettu aiemmin).

Lataaja-luokka huolehtii kurssien ja opintosuunnitelman tietojen lataamisesta tiedostoista. Lataaja-luokassa on toteutettu parseri, joka osaa luoda tiedostoista tarvittavat oliot.

Tallentaja-luokka taas huolehtii kurssien ja opintosuunnitelman tietojen tallentamisesta tiedostoihin myöhempää käyttöä varten. Luokassa on toteutettu metodit, jotka tallentavat kurssien ja opintosuunnitelman tiedot sovitussa tiedostoformaatissa.

GUI-luokka on sovelluksen graafinen käyttöliittymä, jossa on erinäisiä Javan swing-komponentteja ja tapahtuman kuuntelijoita/käsittelijöitä, jotka kyselevät tarvittavia tietoja muilta luokilta.

2. Käyttötapauskuvaus

Otetaan esimerkiksi tapaus: Opiskelijalla on jo olemassa oleva opintosuunnitelma, mutta hän haluaa siirtää yhden kurssin suunnitelmastaan toiselle periodille. Lopuksi hän tallentaa opintosuunnitelmansa.

Kun opiskelija ensin avaa ohjelman käynnistyy graafinen käyttöliittymä (GUI-luokka). GUI lataa automaattisesti kaikkien koulutusohjelmien kurssit muistiin, kun ohjelma käynnistetään. Kurssit on tallennettuina koulutusohjelmittain tiedostoihin, jotka sijaitsevat tietyssä kansiossa. GUI luo tarvittavat oliot Lataaja-luokan kautta, johon on kirjoitettu tarvittava parseri. Parseri taasen luo oliot kutsumalla Koulutusohjelma-luokan metodeja. Opiskelija valitsee sitten käyttöliittymän valikosta "Lataa opintosuunnitelma". Nyt ladataan myös opiskelijan opintosuunnitelman tiedot muistiin. GUI käyttää taas apunaan Lataaja-luokkaa.

Opiskelija siirtyy Opintosuunnitelma-välilehdelle ja valitsee, että suoritukset näytetään periodeittain. GUI pyytää nyt Opintosuunnitelma-luokalta opiskelijan opintosuunnitelman suorituksia järjestettynä periodeittain. Saatu lista näytetään käyttöliittymässä. Kun listaa tulostetaan ruudulle kysyy GUI Suoritus-luokan olioilta kurssikoodeja, kurssien nimiä jne.

Opiskelija valitsee käyttöliittymästä haluamansa suorituksen ja valitsee esim. "Siirrä periodille 1/07". GUI kutsuu Opintosuunnitelma-luokasta metodia, joka palauttaa GUI:lle valitun suorituksen olion ja kutsuu tälle metodia, joka siirtää suorituksen kyseiselle periodille. Metodi tarkistaa, onko kyseisen suorituksen esitietokurssit suoritettu ennen periodia, jolle suoritus aiotaan siirtää. Jos esitietokursseja ei ole suoritettu aiemmin, siirto periodille epäonnistuu ja siitä ilmoitetaan opiskelijalle käyttöliittymässä.

Lopuksi opiskelija tallentaa opintosuunnitelmansa valitsemalla käyttöliittymän valikosta "Tallenna opintosuunnitelma". GUI pyytää nyt Tallentaja-luokkaa tallentamaan opintosuunnitelman tekstitiedostoon. Tallentaja-luokka huolehtii tekstitiedoston oikeasta muodosta.

3. Algoritmit

Sovelluksessa ei ole käytetty mitään kovin mutkikkaita algoritmeja. Suurin osa sovelluksen toiminnasta koostuu siitä, että erilaisista kurssilistoista kysellään tietoja (onko kurssia listassa, listojen tulostusta, listojen päivitystä jne.). Jos sovellukseen toteuttaisi opintosuunnitelman automaattisen generoinnin, tulisi siitä jo hieman mutkikkaampi algoritmi (on vielä hieman epävarmaa, toteutanko tämän ominaisuuden).

Alla sovelluksen muutama "algoritmi":

Suorituksen X siirtäminen jollekin periodille Y tapahtuu seuraavasti: Suoritukseen liittyvän kurssin jokaisesta esitietokurssista tarkastetaan, että ne on valittu suoritettavaksi ennen X:ää eli että niiden suoritusperiodi on aiemmin kuin Y. Jos näin on, päivitetään X:n periodi Y:ksi, muutoin siirtoa ei hyväksytä.

Kun kurssille A lisätään esitietokurssi B, tarkastetaan, että kurssilla B ei ole esitietona kurssia A. Myöskin tarkastetaan, että kurssin B esitietokurssien esitietona ei ole kurssia A jne. Näin vältytään siltä, että eteen tulisi tilanne, jossa pitäisi suorittaa kurssi C, mutta sen esitietona onkin kurssi B, jonka esitietona on kurssi C. Näiden kahden kurssin suorittaminen olisi näin mahdotonta.

Opintosuunnitelman suoritusten listaaminen periodeittain tapahtuu siten, että järjestetään suoritusten kokoelma taulukoihin periodeittain. Suoritusten kokoelma on tallennettu opintosuunnitelmaan järjestämättömäksi hajautusrakenteeksi (HashMap). Iteroidaan hajautusrakenne läpi ja lisätään samalla suorituksia eri taulukoihin sen perusteella, mihin periodiin suoritukset on merkitty. Taulukot järjestetään lopuksi (kurssikoodeittain, käyttäen esim. MergeSort-algoritmia, joka on javassa valmiiksi toteutettu taulukoille - Arrays.sort). Jokaisessa taulukossa on näin vain yhden periodin suorituksia. Taulukot järjestetään lopuksi periodien mukaiseen järjestykseen (tai taulukot voidaan lisätä hajautusrakenteen iteroinnin aikana johonkin tietorakenteeseen, joka pitää yllä järjestystä - esim. TreeMap). Käyttöliittymä voi helposti listata suoritukset periodeittain käymällä läpi tämän rakenteen.

Opintosuunnitelman näyttäminen opintokokonaisuuksittain toimii lähes samalla tavalla kuin edellä, mutta nyt tarkastellaan periodien sijasta opintoja. Lataaja-luokan parserin algoritmi taasen on melko simppeli. Tiedostoa luetaan rivi kerralla ja kun törmätään sovittuihin merkkijonoihin, tehdään jotain sovittua (esim. luodaan uusi Kurssi-olio).

4. Tietorakenteet

Koulutusohjelma-, Opinto ja Opintosuunnitelma-luokkiin on tallennettu kursseja kokoelmiin. Koulutusohjelma-luokassa on kokoelma kyseiseen koulutusohjelmaan kuuluvia kursseja ja lista koulutusohjelman opinnoista (pääaineet, sivuaineet jne.). Opinto-luokassa on kokoelma kyseiseen opintoon kuuluvia kursseja. Opintosuunnitelma-luokassa taas on tallennettu opiskelijan suorituksia (eli valittuja kursseja) kokoelmaan.

Kaikkien näiden kokoelmien tietorakenteeksi on valittu Javan valmis toteutus HashMap, joka pohjautuu hajautusrakenteeseen. Alkioiden hakeminen HashMapistä on tehokasta. Hakuja kurssikoodilla tulee olemaan paljon enemmän kuin lisäyksiä kokoelmiin. Kun GUI:ssa halutaan tarkastella esim. jonkun kurssin tarkempia tietoja, täytyy kurssikoodia vastaava kurssi-olio hakea (ja kurssikoodi luetaan esim. jostain käyttöliittymän tekstikentästä).

Vaihtoehtona olisi ollut myös normaali ArrayList, mutta hakeminen siitä on hitaampaa kuin HashMapistä. Lisäksi HashMap takaa sen, että kokoelmassa ei ole kahta samaa alkiota (kahta saman kurssikoodin omaavaa kurssiahan ei saa olla). Ainoastaan Koulutusohjelma-luokan listaan opinnoista on ehkä järkevää käyttää ArrayListiä, koska opintoja tulee todennäköisesti kuitenkin olemaan melko vähän. Kovin pienille määrille ei ehkä ole järkevää käyttää mitään massiivista tietorakennetta.

Myös TreeMap oli vaihtoehtona kokoelmille, mutta koska en nähnyt järkeä pitää kokoelmia koko ajan järjestyksessä, ei TreeMappiä ole järkevä käyttää. TreeMap kun on hitaampi kuin HashMap. Jos kokoelmaa tarvitsee järjestyksessä (esim. listaus koulutusohjelman kursseista), voidaan HashMapin alkiot siirtää listaan ja järjestää kyseinen lista. Järjestyksessä olevaa kurssilistaa ei kannata generoida joka näyttökerta uudestaan, vaan tallennetaan lista muistiin ja muutetaan sitä vain tarvittaessa (eli kun kursseja lisätään/poistetaan). Opintosuunnitelmassa kursseja taas on hankala pitää järkevässä järjestyksessä, koska kursseja voi kuitenkin tarkastella opintokokonaisuuksittain tai periodeittain (kahta erillistä kokoelmaa ei olisi järkevää ylläpitää).

Taulukko ei näihin rakenteisiin oikein hyvin sovellu, koska on melko mahdotonta tietää, kuinka paljon kursseja sovelluksessa tulee olemaan.

5. Aikataulu

Tarkoituksena on tehdä projektia koko ajan pikkuhiljaa, eikä jättää sitä viimeisille päiville. Lopullista tuntimäärää on näin ollen melko hankala arvioida. Ensin teen Kurssi-, Suoritus- ja Opinto -luokat valmiiksi siten, että niiden perustoiminnot toimivat. Seuraava vaihe on Koulutusohjelma-luokan perustoimintojen toteutus (lisää kurssi, listaa kurssit jne.). Seuraavaksi toteutan Lataaja- ja Tallentaja-luokat, kurssien tietojen tallentamisen/parsimisen osalta. Seuraavaksi on Opintosuunnitelma-luokan vuoro ja viimeisenä on GUI.

Kurssi-, Suoritus- ja Opinto-luokkien toteuttaminen ei pitäisi olla kovin hankalia. Ne kun ovat melko yksinkertaisia luokkia. Opintosuunnitelma ja Koulutusohjelma-luokat taas vaativat hieman enemmän varsinkin, jos niihin toteuttaa opintosuunnitelman automaattisen generoinnin.

Lataaja-luokan parserin kirjoittamisessa tuskin menee hirveästi aikaa. Tiedostoformaatti kun on melko yksinkertainen. Myös Tallentaja-luokka on melko yksinkertainen kirjoittaa. Näihin menee luultavasti muutama tuntia per luokka. GUI:n toteuttamisessa menee varmaankin eniten aikaa, vaikka käyttöliittymän pohjan ajattelinkin tehdä Eclipsen avulla.

6. Yksikkötestaussuunnitelma

Testaamista varten tein pienen Testeri-luokan. Testeri luokkaan sitten kirjoittelen joitain sovelluksen perustoimintoja testaavia koodipätkiä (esim. lisää kurssi koulutusohjelman kurssilistaan, lisää opintosuunnitelmaan jne.) ja ajan ne. Testeri tulostelee sitten toimintojen onnistumisista/epäonnistumisista konsoliin.

Esimerkiksi kurssin lisäämistä sovellukseen voi testata Testeri-luokan avulla kutsumalla Koulutusohjelma-luokasta metodia, joka lisää kurssin. Kun kurssit on lisätty, pyydetään koulutusohjelman kurssien listaamista järjestyksessä ja tulostetaan ne ruudulle. Jos lisätyt kurssikoodit näkyvät ruudulla, pitäisi kurssien lisäys toimia.

Kurssin lisäämistä opintosuunnitelmaan voi testata hyvin samalla tavalla kuin edellä kurssin lisäämistä koulutusohjelman listaan. Muutoinkin kaikki perustoiminnot (esim. suorituksen siirto toiselle periodille) voidaan melko helposti testata suorittamalla ensin toiminto ja sen jälkeen tulostamalla kurssit/suoritukset ruudulle järjestyksessä/periodeittain/opintokokonaisuuksittain.

Lataaja-luokan toteuttaminen melko alussa olisi järkevää, jotta testaaminen hieman suuremmilla kurssimäärillä olisi helpompaa. Lataaja-luokan toimivuudenkin voi helposti tarkistaa tulostamalla kaikkien koulutusohjelmien kurssit ruudulle ja tarkastamalla, näkyykö ruudulla kaikki kurssit, jotka olivat tallennettuina tekstitiedostoihin.

Jos sovelluksessa tapahtuu odottamaton virhe, jonka paikallistaminen on hankalaa, käytän virheen etsintään Eclipsen debuggeria, jolloin olioiden tilaa voi tarkastella juuri ennen virheen tapahtumista.

7. Kirjallisuusviitteet ja linkit

Materiaaleina käytän lähinnä suomenkielistä Java-ohjelmointi -kirjaa sekä Javan APIa ja englanninkielistä Java-tutoriaalia. Lisäksi joskus saatan turvautua Googlen apuun (esim. Javan 2D-piirtoon etsin tietoa Googlella).

Projektityön dokumentti

1. Henkilötiedot

  • Aihe: 306, Opintojen suunnittelija
  • Nimi: Mikko Vestola
  • Päiväys: 01.12.2006

2. Yleiskuvaus

Tarkoituksena oli tehdä sovellus, joka toimii opiskelijan henkilökohtaisena apuvälineenä opintojen suunnitteluun. Opiskelija syöttää ohjelmaan kursseja, jotka hän aikoo suorittaa. Kurssit siirtyvät opiskelijan opintosuunnitelmaan, jota opiskelija voi jälkeenpäin vielä muokata. Opiskelija voi lisätä ja poistaa kursseja opintosuunnitelmastaan ja siirtää kurssien suorituksia eri periodeille tai haluamaansa opintoon (perusopintoihin, suunnan opintoihin, pääaineeseen tai sivuaineeseen). Ohjelma pitää huolen siitä, että kurssien esitietovaatimuksen täyttyvät.

Tarkoituksena oli alun perin tehdä vaatimustasoltaan keskivaativa versio (a) sekä toteuttaa myös joitain vaativan vaikeustason (a+b) toimintoja. Valmis ohjelma on mielestäni toteutettu keskivaativan tasoisena ja lisäksi joitain vaativan vaikeustason toimintoja on myös ohjelmassa (tutkinnon ryhmittely rakenteisiin, osittainen suunnitelman automaattinen generointi).

Ohjelma tehtiin siten, että se sopii yhteen nykyisen tutkintorakenteen kanssa. Eli syys- ja kevätlukukausien tilalle tulevat neljä periodia. Tosin uuteen tutkintorakenteeseen liittyviä moduuleja ei ohjelmaan toteutettu, vaan tutkinnon ryhmittely rakenteisiin tehtiin vanhan tutkintorakenteen mukaan (perusopinnot, suunta jne.)

Opintosuunnitelman esittäminen graafisena esityksenä vaihtui suunnitellusta pylväsesityksestä ympyräkaavio-esitykseen, jossa opiskelija näkee kuinka monta prosenttia hän on suorittanut kunkin opinnon kursseista.

3. Käyttöohje

Kuvankaappaus käyttöliittymästä

Kuvankaappaus käyttöliittymästä: Opintosuunnitelman lataaminen

Ohjelma käynnistetään Gui-luokasta (suorita komentorivillä komento java Gui). Ohjelmassa on graafinen käyttöliittymä. Käyttöliittymän ikkuna on jaettu neljään välilehteen: Hallinta, Kurssit, Opintosuunnitelma ja Opintosuunnitelman tiedot. Lisäksi ikkunassa on valikot: Tiedosto ja Näytä.

Kun ohjelma käynnistetään, lataa se automaattisesti muistiin kaikki kurssit ja opinnot, joiden tiedot on tallennettu koulutusohjelmittain tekstitiedostoihin koulutusohjelmat-kansioon (kansio pitää olla siis samassa kansiossa suhteessa Gui.class-tiedostoon).

Tiedosto-valikosta opiskelija voi ladata oman opintosuunnitelmansa sovelluksen muistiin. Ohjelma kysyy opiskelijan opintonumeroa, jonka perusteella ladataan oikea opintosuunnitelma. Suunnitelman tiedot ladataan suunnitelmat-kansioon tallennetuista tekstitiedostoista.

Hallinta-välilehdeltä voi luoda uusia koulutusohjelmia, opintoja ja kursseja. Ohjelma kysyy tarvittavia tietoja. Opiskelija voi luoda myös uuden opintosuunnitelman. Opiskelija voi tallentaa opintosuunnitelmansa Tiedosto-valikosta. Suunnitelma tallennetaan tekstitiedostona suunnitelmat-kansioon opiskelijanumeron nimellä. Tiedosto-valikosta voi tallentaa myös muokatut kurssit ja opinnot. Kurssit ja opinnot tallentuvat koulutusohjelmittain koulutusohjelmat-kansioon koulutusohjelmien tunnuskirjaimilla. Hallinta-välilehdellä opiskelija voi myös generoida opintosuunnitelmansa. Tällöin ohjelma lisää opiskelijan opintosuunnitelmaan kaikki kurssit, jotka ovat opiskelijalle pakollisia.

Kuvankaappaus käyttöliittymästä

Kuvankaappaus käyttöliittymästä: Kurssien selaaminen

Kurssit välilehdellä opiskelija voi lisätä kursseja suunnitelmaansa. Opiskelija voi tarkastella kursseja koulutusohjelmittain ja lisätä listasta kurssin opintosuunnitelmaan oikean alalaidan "Lisää opintosuunnitelmaan"-napista. Valitun kurssin tiedot näkyvät aina ikkunan oikeassa osassa.

Ohjelma ilmoittaa aina ikkunan alaosassa, onnistuiko kurssin lisääminen vai ei. Ikkunan alaosaan tulostetaan myös muita ilmoituksia toimintojen onnistumisesta/ epäonnistumisesta.

Ohjelman käyttäjä voi siirtyä opintosuunnitelman teosta "Kurssien ja opintojen hallinta" - tilaan valitsemalla Näytä-valikosta "Hallitse kursseja ja opintoja". Nyt käyttäjä voi muokata kurssien tietoja tai lisätä kursseja opintoihin valitsemalla kurssilistasta haluamansa kurssin. "Lisää suunnitelmaan"-painikkeen tilalle ilmestyy nyt painikkeet "Muokkaa kurssia" ja "Lisää opintoon". Muokkaa kurssia -painiketta painamalla pääsee kurssin muokkausikkunaan, jossa voi muokata kurssin tietoja. Se, mitä kenttien sisällöksi pitää antaa, näkyy vihjetekstinä, kun hiiren vie kentän päälle. Näytä-valikosta pääsee taas takaisin "Opintosuunnitelman hallinta" -tilaan.

Kuvankaappaus käyttöliittymästä

Kuvankaappaus käyttöliittymästä: Opintosuunnitelman hallinta

Opintosuunnitelma-välilehdellä opiskelija voi tarkastella suorituksia, joita hänen suunnitelmassaan on. Painamalla hiiren oikeaa näppäintä, voi opiskelija siirtää suorituksen haluamalleen periodille, poistaa suorituksen suunnitelmasta (mikäli kurssi ei ole pakollinen) tai siirtää suorituksen haluamaansa opintoon. Ohjelma ilmoittaa aina, onnistuiko suunnitelman muokkaaminen. Suoritukset voi järjestää joko kurssikoodin mukaisesti, periodin mukaisesti tai sitten opintojen mukaisesti klikkaamalla suoritustaulukon sarakkeiden otsikkoja.

Opintosuunnitelman-tiedot välilehdellä opiskelija voi tarkastella, mitkä ovat hänen pää- ja sivuaineensa jne. Ohjelma näyttää ympyräkaavioina, kuinka monta prosenttia opiskelija on suorittanut opinnoistaan. Ohjelma vertaa kurssien suoritusajankohtia tietokoneen kelloon ja laskee sen perusteella, onko suoritus suoritettu vai vasta suunnitteilla.

4. Ohjelman rakenne

Ohjelma on jaoteltu seuraaviin luokkiin:

  • Koulutusohjelma
  • Kurssi
  • Opinto
  • Opintosuunnitelma
  • Suoritus
  • Tallentaja
  • Lataaja
  • Gui
  • ImageComponent
  • KurssiDialog
  • KurssiTaulukko
  • PonnahdusNayttaja
  • SuoritusTaulukko
  • TableSorter
  • Ympyrakaavio

Luokkajako on tehty ajatellen reaalimaailmaa TKK:ssa. Jokin koulutusohjelma tarjoaa kursseja ja opintoja (perusopinnot, pääaineita, sivuaineita jne.), jotka koostuvat kursseista. Opiskelijan opintosuunnitelma taas koostuu suorituksista, jotka ovat kursseja suoritettuna tiettynä aikana (tai suunniteltu suoritettavan). Suoritukset kuuluvat johonkin opiskelijan valitsemaan opintoon (esim. perusopintoihin, suuntaan tai sivuaineeseen).

Koulutusohjelma-luokka mallintaa eri koulutusohjelmia. Koulutusohjelmat tarjoavat kursseja ja opintoja. Koulutusohjelmalla on siis lista kursseista ja opinnoista, joita se voi tarjota. Keskeisiä metodeja ovat seuraavat: listaa kurssit järjestyksessä kurssikoodeittain, listaa kurssit opintokokonaisuuksittain (pääaineet, perusopinnot jne.), lisää kurssi koulutusohjelmaan, poista kurssi ja etsi kurssi, joka palauttaa etsittävän kurssikoodin omaavan olion.

Kurssi-luokka mallintaa nimensä mukaisesti kursseja. Kurssilla on nimi, kurssikoodi, opintopistemäärä, periodit, jolloin se järjestetään, kuvaus ja lista kurssikoodeista, jotka ovat kurssin esitietoina. Kurssi-luokan keskeisiä metodeita ovat normaalien saantimetodien (kerroNimi, kerroKurssikoodi jne...) lisäksi metodi, joka lisää kurssin esitietovaatimusten listaan halutun kurssikoodin sekä poista- ja muokkaa kurssia metodit. Jos kurssi poistetaan, ei tietoja kurssista poisteta, vaan periodit, jolloin kurssi järjestetään merkitään kaikki tyhjiksi. Näin he, jotka ovat suorittaneet jo kyseisen kurssin voivat yhä tarkastella kurssin tietoja.

Opinto-luokka kuvaa koulutusohjelman opintoja (perusopinnot, pääaineen opinnot, suunnan opinnot jne.). Opinnolla on aina nimi (esim. "Tietojenkäsittelyteorian pääaine"), tyyppi (perusopintoja, pääaine, sivuaine jne.), laajuus opintopisteinä sekä listat opintoon kuuluvista pakollisista ja vapaavalintaista kursseista. Opinto-luokan keskeisiä metodeja ovat: lisää kurssi opintoon (tarkastaa, ettei kurssia ole jo opinnossa), tarkasta onko parametrina annettu kurssi pakollinen (eli onko pakollisten kurssien listassa) ja kuuluuko parametrina annettu kurssi opintoon.

Opintosuunnitelma-luokka kuvaa opiskelijan opintosuunnitelmaa. Opintosuunnitelmassa on tallennettuna, kenelle opiskelijalle suunnitelma kuuluu (nimi ja opiskelijanumero), sekä valitut pää- ja sivuaineet sekä suunta. Suunnitelmassa on myös listattu kaikki ne suoritukset, jotka opiskelija on valinnut suoritettavakseen. Keskeisiä metodeja ovat suoritusten listaaminen periodeittain/opintokokonaisuuksittain, kurssin lisääminen opintosuunnitelmaan, suorituksen etsiminen suunnitelmasta (palauttaa kurssikoodia vastaavan suoritus-olion) ja metodi, joka tarkastaa onko suunnitelman kaikkien suoritusten esitietovaatimukset suoritettuna.

Suoritus-luokka kuvaa opiskelijan valitseman kurssin suoritusta. Suoritus koostuu kurssista sekä periodista ja lukuvuodesta, jolloin kurssi on ajateltu suorittaa. Suoritus kuuluu lisäksi johonkin opintoon (tai jos ei kuulu, se tulkitaan kuuluvan vapaavalintaisiin opintoihin). Keskeisiä metodeja ovat: siirto toiselle periodille, siirto toiseen opintoon ja esitietokurssien tarkastus (että on suoritettu aiemmin) sekä metodi, joka kertoo, onko suoritus jo suoritettu (vai vasta suunnitteilla).

Lataaja-luokka huolehtii kurssien ja opintosuunnitelman tietojen lataamisesta tiedostoista. Lataaja-luokassa on toteutettu parseri, joka osaa luoda tiedostoista tarvittavat oliot. Keskeiset metodit ovat opintosuunnitelman lataaminen tiedostosta sekä kurssien ja opintojen lataaminen tiedostosta.

Tallentaja-luokka taas huolehtii kurssien ja opintosuunnitelman tietojen tallentamisesta tiedostoihin myöhempää käyttöä varten. Luokassa on toteutettu metodit, jotka tallentavat kurssien ja opintosuunnitelman tiedot sovitussa tiedostoformaatissa. Keskeiset metodit ovat opintosuunnitelman tallentaminen tiedostoon sekä kurssien ja opintojen tallentaminen tiedostoon.

Gui-luokka on sovelluksen graafinen käyttöliittymä, jossa on erinäisiä Javan swing-komponentteja ja tapahtuman kuuntelijoita/käsittelijöitä, jotka kyselevät tarvittavia tietoja muilta luokilta. Keskeisiä metodeja ovat: ikkunan komponenttien alustaminen (välilehdet, valikot, painikkeet jne.), opintosuunnitelman lataaminen ja tallentaminen, kurssien ja opintojen tallentaminen, kurssitaulukon ja suoritustaulukon päivittäminen, kurssin ja suorituksen tietojen päivittäminen (näyttää kurssi-/suoritustaulukossa valitun kurssin tiedot), uuden koulutusohjelman/opinnon/kurssin luonti, kurssin lisääminen opintosuunnitelmaan, kurssin tietojen muokkaaminen sekä suorituksen siirtäminen toiseen periodiin.

ImageComponent-luokka on tarkoitettu kuvien näyttämiseen Gui:n ikkunassa (ohjelmassa on Hallinta-välilehdellä yksi gif-kuva). Luokan keskeiset metodit ovat konstruktori, joka lataa kuvan tiedostosta Image-olioksi sekä paint-metodi, joka piirtää ladatun kuvan näytölle.

KurssiDialog-ikkuna

KurssiDialog-ikkuna

KurssiDialog-luokka on pieni ikkuna, jossa voi muokata kurssin tietoja (nimi, periodit, opintopisteet, kuvaus jne.). Luokkaa käytetään uuden kurssin luomisessa ja olemassa olevan kurssin tietojen muokkaamiseen. Luokkaa kutsutaan Gui-luokasta. Keskeisin metodi on konstruktori, joka luo ja näyttää ikkunan (luo tarvittavat tekstikentät ja painikkeet sekä hakee niihin kurssin tiedot, jos kyseessä on kurssin muokkaus). Toinen keskeinen metodi on metodi, joka suorittaa kurssin tietojen muokkaamisen (lukee ikkunan kenttiin kirjoitetut arvot ja muokkaa kurssin tiedot vastaaviksi).

KurssiTaulukko-luokka kuvaa taulukkomallia koulutusohjelman kursseista. Tällä taulukkomallilla on datana jonkun koulutusohjelman sisältämät kurssit. Taulukkomallilta voi käydä kyselemässä rivien ja sarakkeiden määriä, sarakeotsikoita ja tietyn taulukon solun sisältämää alkiota. Gui-luokka käyttää taulukkomallia Kurssit-välilehden kurssit-taulukossa. KurssiTaulukko-luokan keskeisiä metodeja ovat rivien ja sarakkeiden määrän laskeminen, sarakeotsikoiden nimien palauttaminen ja tietyn taulukon solun arvon palauttaminen sekä taulukkomallin sisältämän datan päivittäminen.

SuoritusTaulukko-luokka on vähän kuten KurssiTaulukko-luokka, mutta nyt taulukkomallin datana on suorituksia kurssien sijaan. Keskeiset metodit ovat hyvin samanlaisia kuin KurssiTaulukko-luokassa. Gui-luokka käyttää SuoritusTaulukko-taulukkomallia Opintosuunnitelma-välilehden suoritus-taulukossa.

PonnahdusNayttaja-luokka on tarkoitettu Gui-ikkunan Opintosuunitelma-välilehdellä käytettävän ponnahdusvalikon näyttämiseen (kun painitaan suorituksen kohdalla hiiren oikeaa painiketta). Keskeisin metodi on metodi, joka näyttää ponnahdusvalikon.

TableSorter-luokka on lainattu suoraan Javan tutoriaaleista. Luokka on tarkoitettu JTable-taulukkokomponentin sisällön järjestämiseen sarakkeittain. Luokkaa käytetään Gui-ikkunan Kurssit- ja Opintosuunnitelma -välilehtien taulukoissa. TableSorter siis ikään kuin asettuu ikkunan ja taulukkomallin väliin. Normaalisti, kun taulukko piirretään näytölle, käy ohjelma kysymässä taulukkomallilta, mitä arvoja taulukon soluissa on. Kun käytetään TableSorter-luokkaa, käykin ohjelma kysymässä TableSorterilta taulukon solujen tietoja ja TableSorter välittää kyselyt eteenpäin siihen rekisteröityyn taulukkomalliin (eli SuoritusTaulukkoon tai KurssiTaulukkoon). TableSorter sitten pitää huolta, että se kertoo ohjelmalle taulukon solujen arvot halutussa järjestyksessä.

Ympyrakaavio-luokka esittää nimensä mukaisesti ympyrän muotoista kaaviota, joka on tarkoitettu esittämään havainnollisesti, kuinka monta prosenttia opintosuunnitelman jostain opinnosta on suoritettu. Gui-ikkuna käyttää näitä ympyräkaavioita Opintosuunnitelman tiedot -välilehdellä. Keskeisimpiä metodeja ovat ympyräkaavion piirtäminen, konstruktori, joka alustaa ympyräkaavion sekä metodi, joka päivittää ympyräkaavion sisältämän prosenttiarvon.

5. Algoritmit

Sovelluksessa ei ole käytetty mitään kovin mutkikkaita algoritmeja. Suurin osa sovelluksen toiminnasta koostuu siitä, että erilaisista kurssilistoista kysellään tietoja (onko kurssia listassa, listojen tulostusta, listojen päivitystä jne.). Alla on esitetty sovelluksen muutama algoritmi:

Suorituksen siirto periodille

Suorituksen X siirtäminen jollekin toiselle suoritusajankohdalle Y (eli vuosi ja periodi) tapahtuu pääpiirteittäin seuraavasti: Otetaan X:n nykyinen suoritusajankohta Z ylös ja merkitään X:n suoritusajankohdaksi uusi suoritusajankohta Y. Tarkastetaan sitten, järjestetäänkö suoritukseen kuuluvaa kurssia kyseisellä periodilla Y tai sotkeeko suorituksen siirtäminen uudelle periodille opintosuunnitelman muiden suoritusten esitietovaatimukset. Opintosuunnitelmassa kun voi olla suoritus A, jonka esitietona on suoritus X. Jos X:n suoritusajankohta valitaan siten, että se on A:n jälkeen, ei A:n esitietovaatimuksia ole suoritettu. Suorituksen siirto voi siis aiheuttaa sen, että opintosuunnitelman jonkun suorituksen esitietovaatimukset rikkoutuvat. Jos kurssi järjestetään periodilla Y ja siirto ei sotke suunnitelman muiden suoritusten esitietovaatimuksia, on siirto onnistunut. Muutoin merkitään X:n suoritusajankohdaksi alkuperäinen suoritusajankohta Z ja ilmoitetaan, että siirto epäonnistui.

Opintosuunnitelman generointi

Opintosuunnitelman generoiva algoritmi on melko yksinkertainen (ja tosin hieman vajaa). Algoritmi käy läpi opiskelijan perusopintojen ja hänen valitsemansa suunnan, pääaineen ja sivuaineen kaikki pakolliset kurssit ja yrittää lisätä ne suunnitelmaan. Algoritmia olisi voinut vielä jatkaa niin, että se lisäisi myös valinnaisia kursseja siten, että opintosuunnitelmaan tulee lisättyä kursseja sen verran, että jokainen opiskelijan valitsema opinnon kokonaislaajuus tulee täyteen. Nyt suunnitelmaan lisätään vain pakolliset kurssit ja opiskelija joutuu manuaalisesti lisäämään oikean määrän valinnaisia kursseja suunnitelmaansa.

Algoritmia olisi voinut jatkaa myös siten, että suoritukset olisi lisätty automaattisesti optimaalisimpiin periodeihin (esim. suorituksia 20 op / periodi). En kuitenkaan keksinyt tähän mitään järkevää algoritmia. Jonkinlaista kurssien priorisointia olisi kaiketi pitänyt toteuttaa. Nyt kun kurssi lisätään suunnitelmaan, lisätään se vain oikeaan opintoon, mutta millekään periodille sitä ei automaattisesti laiteta.

Kurssin lisääminen suunnitelmaan

Aluksi tarkastetaan, että kyseistä kurssia ei ole jo suunnitelmassa. Jos ei ole, lisätään kurssi suunnitelmaan. Automaattisesti myös tarkistetaan, kuuluuko kurssi johonkin opiskelijan opintoon (perusopinnot, suunta, pääaine tai sivuaine). Jos kuuluu, siirretään suoritus suoraan tähän opintoon.

Suoritukset poistaminen suunnitelmasta

Tarkastetaan ensin, että suoritus ei ole suoritettu. Suoritettua kurssia ei voi poistaa suunnitelmasta. Seuraavaksi tarkastetaan, onko suoritukseen liittyvä kurssi pakollinen osa sitä opintoa, johon se kuuluu. Jos on, ei suoritusta voi poistaa suunnitelmasta, koska se on kuitenkin pakko joskus suorittaa. Jos nämä ehdot toteutuvat, poistetaan suoritus suunnitelmasta. Nyt tarkastetaan, onko suorituksen poisto rikkonut opintosuunnitelman muiden kurssien esitietovaatimuksia. Jos on rikkonut, palautetaan suoritus takaisin suunnitelmaan. Muutoin suorituksen poistaminen on onnistunut.

Opintosuunnitelman suoritusten esitietojen tarkastus

Opintosuunnitelman kaikkien suoritusten esitietojen tarkastus tapahtuu yksinkertaisesti siten, että iteroidaan suunnitelman kaikki suoritukset läpi ja tarkastetaan jokaisesta suorituksesta yksitellen, onko sen esitietovaatimukset suoritettu (tai valittu suoritettavaksi aikaisemmin). Yksittäisen suorituksen esitietojen tarkastus taas tapahtuu seuraavasti:

Ensin tarkastetaan, onko suoritukseen liittyvällä kurssilla yhtään esitietokursseja. Jos ei ole, on suorituksen esitietovaatimukset automaattisesti suoritettu. Muutoin käydään kurssin esitietokurssit yksi kerrallaan läpi. Algoritmi käy läpi kurssin jokaisen esitietokurssin ja myös esitietokurssien esitietokurssit rekursiivisesti jne. ja tarkastaa, onko esitietokurssi suoritettu (tai valittu suoritettavaksi) aikaisemmin kuin tarkastelussa oleva kurssi.

Otetaan esimerkiksi, että kurssilla A on esitietokurssit B ja C ja B:llä on esitietokurssi D. Ensin tarkastetaan, onko A:n esitietokurssit suoritettu. Algoritmi aloittaa kurssista B ja vertaa A:n ja B:n suoritusajankohtia. Jos A on suoritettu (tai valittu suoritettavaksi) aikaisemmin kuin B, ei A:n esitietokursseja ole suoritettu. Jos taas B on suoritettu aikaisemmin kuin A, kuten pitääkin, siirrytään tarkastelemaan B:n esitietokursseja. B:n esitietokursseille tehdään nyt sama tarkastelu kuin A:n esitietokursseille. Eli verrataan B:n ja D:n suoritusajankohtia. Lopulta päädytään sellaiseen kurssiin, jolla ei ole esitietokursseja (D). Kun B:n esitiedot on tarkastettu, lopuksi verrataan A:n ja C:n suoritusajankohtia vastaavasti.

Onko suoritus suoritettu?

Algoritmi vertaa järjestelmän tämänhetkistä päivämäärää suorituksen loppumisajankohtaan (eli siihen vuoteen ja periodiin, jolloin suoritus loppuu). Algoritmiin on koodattu periodien loppumisajankohdat ja sen perusteella lasketaan, onko suoritus suoritettu vai ei. Tämän olisi myös voinut toteuttaa niin, että opiskelija olisi manuaalisesti aina valinnut, milloin kurssi on suoritettu. Näin homma hoituu kuitenkin mielestäni kätevämmin. Opiskelija voi aina siirtää suorituksen seuraavalle periodille, jos ei päässytkään kurssia läpi.

Suunnitelman suoritusten järjestäminen

Opintosuunnitelman suoritusten listaaminen periodeittain tapahtuu siten, että järjestetään suoritusten kokoelma taulukkoon periodeittain. Suoritusten kokoelma on tallennettu opintosuunnitelmaan järjestämättömäksi hajautusrakenteeksi (HashMap). Iteroidaan hajautusrakenne läpi ja lisätään samalla suorituksia taulukkoon. Taulukko järjestetään lopuksi käyttäen MergeSort-algoritmia, joka on Javassa valmiiksi toteutettu taulukoille - Arrays.sort. Taulukko voidaan järjestää näin helposti, koska Opintosuunnitelmaan on toteutettu kaksi järjestelijää: toinen järjestää taulukon periodeittain ja toinen opinnoittain. Käyttöliittymä voi helposti listata suoritukset periodeittain käymällä läpi tämän taulukon.

Kurssien ja suunnitelman tallentaminen/lataaminen

Lataaja-luokan parserin algoritmi on melko simppeli. Tiedostoa luetaan rivi kerralla ja kun törmätään sovittuihin merkkijonoihin, tehdään jotain sovittua (esim. luodaan uusi Kurssi-olio). Tallentaja luokan algoritmi taas yksinkertaisesti tallentaa kursseista, opinnoista ja suunnitelmista tarvittavat tiedot sovitussa tiedostoformaatissa.

6. Tietorakenteet

Koulutusohjelma-, Opinto ja Opintosuunnitelma-luokkiin on tallennettu kursseja kokoelmiin. Koulutusohjelma-luokassa on kokoelma kyseiseen koulutusohjelmaan kuuluvia kursseja ja kokoelma koulutusohjelman opinnoista (pääaineet, sivuaineet jne.). Opinto-luokassa on kokoelma kyseiseen opintoon kuuluvia kursseja. Opintosuunnitelma-luokassa taas on tallennettu opiskelijan suorituksia (eli valittuja kursseja) kokoelmaan.

Kaikkien näiden kokoelmien tietorakenteeksi on valittu Javan valmis toteutus HashMap, joka pohjautuu hajautusrakenteeseen. Alkioiden hakeminen HashMapistä on tehokasta. Hakuja kurssikoodilla tulee olemaan paljon enemmän kuin lisäyksiä kokoelmiin. Kun Gui:ssa halutaan tarkastella esim. jonkun kurssin tarkempia tietoja, täytyy kurssikoodia vastaava kurssi-olio hakea (kurssikoodi luetaan käyttöliittymän tekstikentästä tai käyttäjän antamasta syötteestä, jos kyseessä olisi merkkipohjainen käyttöliittymä). Taulukko ei näihin rakenteisiin soveltunut, koska on melko mahdotonta tietää, kuinka paljon kursseja sovelluksessa tulee olemaan.

Vaihtoehtona olisi ollut myös normaali ArrayList, mutta hakeminen siitä on hitaampaa kuin HashMapistä. Lisäksi HashMap takaa sen, että kokoelmassa ei ole kahta samaa alkiota (kahta saman kurssikoodin omaavaa kurssiahan ei saa olla).

Kurssi-luokassa esitietokurssit on tallennettu yksinkertaiseen ArrayListiin. Esitietokursseja on kun on kursseilla yleensä melko vähän, joten niihin ei ole järkevää käyttää mitään kovin massiivista tietorakennetta. Taulukko ei kuitenkaan tullut kysymykseen, koska jos kurssille lisää esitietokurssin, täytyisi luoda aina uusi taulukko. ArrayList on tähän kätevämpi vaihtoehto.

KurssiTaulukko- ja SuoritusTaulukko -luokissa käytetään taulukkoa, johon kurssit ja suoritukset tallennetaan. Tämä siksi, että näistä taulukkomalleista pitää pystyä hakemaan tietoa tietystä taulukon solusta. HashMapistä tällainen haku ei onnistu, muutoin kuin iteroimalla, joka ei olisi järkevä ratkaisu, koska iterointi pitäisi tehdä aina jokaisella hakukerralla uudestaan.

Myös TreeMap oli vaihtoehtona kokoelmille, mutta koska en nähnyt järkeä pitää kokoelmia koko ajan järjestyksessä, ei TreeMappiä ole järkevä käyttää. TreeMap kun on hitaampi kuin HashMap. Jos kokoelmaa tarvitsee järjestyksessä (esim. listaus koulutusohjelman kursseista), voidaan HashMapin alkiot siirtää taulukkoon ja järjestää kyseinen taulukko.

7. Tiedostot

Tiedot kursseista, opinnoista ja opintosuunnitelmasta tallennetaan ns. perus tekstimuotoisina tiedostoina. Näin tiedostoja on helppo muokata käsin ja niiden parsiminen on silti melko yksinkertaista. Mielestäni on tärkeää, että esimerkiksi kursseja on helppo editoida/lisätä suoraan tekstitiedostoon (sovelluksen graafinen käyttöliittymä kun ei ole välttämättä se nopein tapa lisätä kursseja).

Kurssien ja opintojen tietojen tallennusformaatti

Tiedot kursseista ja opinnoista tallennetaan koulutusohjelmittain koulutusohjelmat-kansioon. Tiedostojen nimiksi tulee koulutusohjelman tunnus (esim. Tietotekniikan koulutusohjelman tunnus on T, joten tiedostonimeksi tulee T.txt). Tiedostoon tallennetaan koulutusohjelman tunnus ja nimi. Lisäksi tallennetaan tiedot jokaisesta koulutusohjelman opinnosta (nimi, tyyppi, laajuus, pakolliset ja valinnaiset kurssit). Jokaisesta kurssista tallennetaan niin ikään kurssikoodi, nimi, kuvaus, tieto onko kurssi poistettu, opintopisteet, kesto, periodit sekä kurssin esitietokurssit. Tiedostoformaatti näyttää seuraavalta:

<<< Opintoapuri v0.1 >>>

#==KOULUTUSOHJELMAN TIEDOT ALKAA==#

#Tunnus
T
#Nimi
Tietotekniikka

#==KOULUTUSOHJELMAN TIEDOT LOPPUU==#


#==KOULUTUSOHJELMAN OPINNOT ALKAA==#

#Nimi
Perusopinnot
#Tyyppi
Perusopinnot
#Laajuus
80
#Pakolliset kurssit
Mat-1.1110
Mat-1.1120
Mat-1.1311
Mat-1.2600
Mat-1.2620
Tfy-3.1241
Tfy-3.1242
Tfy-3.1253
Tfy-3.1254
T-0.1001
T-106.1200
T-106.1220
T-106.1240
T-79.1001
T-76.2143
T-110.2100
T-111.2350
T-121.2100
T-61.2010
#Valinnaiset kurssit
T-121.3110
Tfy-3.1530
Tfy-3.1540
Mat-2.2107
Mat-1.1132
TU-22.1101
TU-22.1103
T-128.2101

#Nimi
Tietojenkäsittelyteoria
#Tyyppi
Suunta
#Laajuus
40
#Pakolliset kurssit
T-106.3100
T-76.3601
T-79.3001
T-0.3123
T-79.4001
T-79.4201
T-79.4301
T-79.4501
T-106.4100
#Valinnaiset kurssit

#==KOULUTUSOHJELMAN OPINNOT LOPPUU==#


#==KOULUTUSOHJELMAN KURSSIT ALKAA==#


#Kurssikoodi
T-0.1001
#Nimi
Johdatus opiskeluun T-tutkinto-ohjelmassa
#Kuvaus
xxxxx
#Poistettu
false
#Op
2
#Kesto
1
#Periodit
1,3
#Esitiedot

#Kurssikoodi
T-106.1200
#Nimi
Ohjelmoinnin perusteet T (Java)
#Kuvaus
Java-ohjelmoinnin perusteet.
#Poistettu
false
#Op
5
#Kesto
2
#Periodit
1
#Esitiedot
T-0.1001

#Kurssikoodi
T-106.1220
#Nimi
Tietorakenteen ja algoritmit T
#Kuvaus
xxxxx
#Poistettu
false
#Op
5
#Kesto
2
#Periodit
3
#Esitiedot
T-0.1001
T-106.1200

#==KOULUTUSOHJELMAN KURSSIT LOPPUU==#

Periodit, jolloin kurssi järjestetään erotellaan siis pilkuilla. Huom! Tekstitiedostossa periodien jälkeen pitää olla rivinvaihto, vaikkei kurssia järjestettäisikään millään periodilla. Esitietokurssit listataan jokainen omalle rivilleen. Poistettu-arvoksi käy joko true tai false.

Opintosuunnitelman tietojen tallennusformaatti

Opintosuunnitelman tiedot tallennetaan jokaiselle opiskelijalle erikseen suunnitelmat-kansioon. Tiedostojen nimiksi tulee opiskelijan opiskelijanumero (esim. opiskelijanumerolla 12345A tiedostonimeksi tulee 12345A.txt). Tiedostoon tallennetaan opiskelijan nimi, opiskelijanumero, koulutusohjelman tunnus, valitut suunta, pääaine ja sivuaine sekä tiedot opintosuunnitelman suorituksista (kurssikoodi, suoritusajankohta, suorituksen opinto). Tiedostoformaatti näyttää seuraavalta:

<<< Opintoapuri v0.1 >>>

#==OPINTOSUUNNITELMAN TIEDOT ALKAA==#

#Opiskelijan nimi
Teemu Teekkari
#Opiskelijanumero
12345A
#Koulutusohjelma
T
#Suunta
Mediatekniikka
#Pääaine
Käyttöliittymät ja käytettävyys
#Sivuaine
Teollisuustalous :: TU

#==OPINTOSUUNNITELMAN TIEDOT LOPPUU==#

#==OPINTOSUUNNITELMAN SUORITUKSET ALKAA==#

#Kurssikoodi
T-0.1001
#Lukuvuosi
2003
#Periodi
1
#Opinto
Perusopinnot

#Kurssikoodi
T-111.4003
#Lukuvuosi
0
#Periodi
0
#Opinto
Suunta

#Kurssikoodi
T-121.5400
#Lukuvuosi
0
#Periodi
0
#Opinto
Pääaine

#Kurssikoodi
TU-22.1120
#Lukuvuosi
2005
#Periodi
2
#Opinto
Sivuaine

#Kurssikoodi
Mat-2.2107
#Lukuvuosi
0
#Periodi
0
#Opinto
Vapaavalintaiset

#==OPINTOSUUNNITELMAN SUORITUKSET LOPPUU==#

Sivuaine ilmoitetaan siis muodossa: (Sivuaineen nimi) :: (Koulutusohjelman tunnus, johon sivuaine kuuluu). Jos suorituksen suoritusajankohtaa ei ole valittu, merkitään periodiksi ja vuodeksi 0. Suoritus voi kuulua johonkin seuraavasta viidestä opinnosta: Perusopinto, Suunta, Pääaine, Sivuaine tai Vapaavalintaiset.

8. Testaus

Testaaminen tapahtui suunnitelman mukaisesti. Aluksi testasin luokkien perustoimintoja pienellä Testeri-luokalla, johon kirjoittelin joitain luokkien perustoimintoja testaavia koodinpätkiä (esim. lisää kurssi koulutusohjelman kurssilistaan, listaa koulutusohjelman kurssit jne.). Testeri tulosteli toimintojen onnistumisista konsoliin.

Kun kaikkien luokkien perustoiminnot olivat valmiina, tein graafisen käyttöliittymän ja ryhdyin testaamaan sovelluksen toimivuutta graafisesti ja heivasin Testeri-luokan mäkeen. Ohjelman toimivuutta oli helppo testata suuremmilla kurssimäärillä, kun Lataaja- ja Tallentaja-luokat oli toteutettu.

Testauksen aikana havaittujen virheiden lähteet löysi yleensä aika helposti, mutta joskus virheiden lähteitä sai etsiä pitkäänkin. Tässä suurena apuna oli Eclipsen debuggeri (esim. yhtä virhettä en olisi ilman debuggeria koskaan löytänyt, kun periodi ja vuosi olivat vaihtaneet jossain välissä paikkojaan).

9. Ohjelman tunnetut puutteet ja viat

Pääainetta ja suuntaa ei voisi oikeasti valita mielivaltaisesti (siihen, minkä pääaineen voi valita, vaikuttaisi oikeasti aikaisempi suunnan valinta). Nyt opiskelija voi kuitenkin valita pääaineen ja suunnan mielivaltaisesti (tosin vain omasta koulutusohjelmastaan).

Opintoihin voi sisällyttää enemmän kursseja kuin opinnon kokonaislaajuus on (onko tämä sitten mahdollista oikeasti?). Vapaavalintaisten kurssien määrää kun ei ohjelmassa tarkasteta.

Opintoja ei voi muokata graafisesti. Opintoihin voi lisätä kursseja graafisesti, mutta muuten sitä ei voi muokata jälkeenpäin muuta kuin muokkaamalla koulutusohjelmat-kansion tekstitiedostoja.

Parserit eivät ole kovin virheensietoisia. Ylimääräisistä välilyönneistä parserien kyllä pitäisi selviytyä, mutta jos tiedot ovat kirjoitettu tiedostoihin väärässä järjestyksessä tai rivinvaihtoja uupuu, voi parseri mennä sekaisin.

Kurssin poistamisen kanssa on hieman ongelmia. Alun perin tarkoituksena oli, että kun kurssi poistetaan, ei sitä varsinaisesti poisteta, vaan se vain merkitään siten, että kurssia ei enää järjestetä. Näin opiskelija voi yhä tarkastella kurssin tietoja (kurssikuvaus, opintopisteet jne.) suunnitelmassaan. Kun kurssin poistaa, ei sitä voi enää kukaan valita opintosuunnitelmaansa. Kuitenkin he, jotka ovat jo lisänneet kurssin suunnitelmaansa ennen poistoa, eivät voi suorittaa kurssia, koska sitä ei enää järjestetä millään periodilla. Toisaalta opiskelija ei voi myöskään poistaa kurssia suunnitelmastaan, jos se on pakollinen kurssi. Kurssin poiston yhteydessä pitäisikin kurssi poistaa myös jokaisesta opinnosta, jossa se on pakollinen.

10. 3 parasta ja 3 heikointa kohtaa

Onnistuneita kohtia

  • Onnistunut luokkajako
  • Graafinen käyttöliittymä
  • Selkeä ohjelmakoodi

Heikkoja kohtia

  • Graafisessa käyttöliittymässä tapahtumien virheilmoitukset eivät ole kaikkein kuvaavimpia. Kaikista virheistä ei anneta aina kovin tarkkaa virheilmoitusta vaan ilmoitetaan vain, että toiminto on epäonnistunut. Virheilmoituksista olisi voinut siis tehdä hieman tarkempia.

11. Poikkeamat suunnitelmasta

Suurimmalta osalta projektin toteuttaminen meni kuten suunnittelin. Joidenkin algoritmien toimintaa jouduin kuitenkin muuttamaan.

Alun perin suorituksen siirto periodille piti tapahtua niin, että vain siirrettävän suorituksen esitietokurssien suoritusajankohdat tarkastetaan (että on suoritettu aikaisemmin kuin siirrettävä suoritus). Tajusin kuitenkin, että siirrettävä suoritus saattaa olla myös muiden suoritusten esitietona, jolloin sen siirto voisi rikkoa muiden suoritusten esitietovaatimukset. Nyt kun suoritus siirretään periodille, tarkastetaan jokaisesta opintosuunnitelman suorituksesta, joiden suoritusajankohta on asetettu, että suorituksen esitietokurssit on suoritettu/suunnitteilla aikaisemmin kuin tarkasteltava suoritus (ja tämä tehdään rekursiivisesti myös esitietokurssien esitietokursseille). Myös kurssin kesto huomioidaan siinä, milloin seuraavaa kurssia voi alkaa suorittamaan.

Suunnitelmassa kerroin, että kun kurssille A lisätään esitietokurssi B, tarkastetaan, että kurssilla B ei ole esitietona kurssia A. Myöskin tarkastetaan, että kurssin B esitietokurssien esitietona ei ole kurssia A jne. Luovuin kuitenkin tästä tarkastelusta, koska kun kurssien tietoja parsii tekstitiedostosta, ei kaikkia kursseja välttämättä ole vielä muistissa, jolloin esitietokurssien tarkastaminen on mahdotonta.

Opintosuunnitelman suoritusten listaaminen periodeittain muuttui myös. Alun perin suoritukset piti iteroida eri taulukoihin periodeittain (kts. tekninen suunnitelma). Tästä rakenteesta tuli kuitenkin mielestäni turhan monimutkainen, joten päädyin lopulta vain lukemaan suoritukset yhteen ainoaan taulukkoon ja järjestämään suoritukset siinä periodeittain.

Käyttöliittymästäkään ei tullut aivan sama kuin aluksi suunnittelin. Muutokset tosin olivat lähinnä vain kosmeettisia. Käyttöliittymän rakenne pysyi hyvin samanlaisena (ikkuna jaettuna välilehtiin ja osa välilehdistä jaettuna kahteen osaan).

Myös opintosuunnitelman esittäminen graafisesti muuttui. Opintosuunnitelma oli tarkoitus esittää graafisesti pylväsesityksenä, jossa näkyisi, kuinka paljon opintoja (=opintopisteitä) on valittu kullekin periodille. En kuitenkaan keksinyt tähän mitään järkevää toteutusta, joten lopulta päädyin ympyräkaavio-esitykseen, jossa näkee kuinka monta prosenttia opiskelija on suorittanut opinnoistaan.

Suunnitelmassa kerroin tekeväni käyttöliittymän pitkälti Eclipsen graafisella käyttöliittymän piirto-työkalulla (Visual Editor). Hyvin nopeasti luovuin tästä ja tein koko käyttöliittymän käsin koodaten. Visual Editor kun oli järkyttävän hidas, kun tavaraa alkoi tulla ruudulle hiemankin enemmän ja ohjelma myös bugaili sen verran, että sitä oli lähes mahdoton käyttää. Käsin koodaaminen oli nopeampaa ja siitä oppikin paljon enemmän.

12. Toteutunut työjärjestys ja aikataulu

Projektin toteuttaminen meni suurin piirtein niin kuin suunnittelinkin. Alun perin tarkoituksena oli tehdä projektia koko ajan pikkuhiljaa. Mitään tuntimääräistä arviota en aluksi tehnyt. Yleissuunnitelmaan ja tekniseen suunnitelmaan meni aikaa yhteensä arviolta noin 20 tuntia. Itse koodaaminen taas sijoittui suunnilleen aikavälille 3.11 - 20.11. Tämän jälkeen en enää paljoa aikaa koodaamiseen käyttänyt - lähinnä pientä ohjelman viilailua. Aikaa koodaamiseen meni noin 70 tuntia (tähän on siis laskettu vain koneen ääressä tapahtuva koodin kirjoitus). Dokumentoinnin tekoon aikaa taas meni arviolta 15 tuntia.

Luokkien toteutusjärjestys meni suunnilleen niin kuin ajattelinkin. Eli aluksi toteutin Kurssi-, Suoritus- ja Opinto -luokat valmiiksi siten, että niiden perustoiminnot toimivat. Seuraava vaihe oli Koulutusohjelma-luokan perustoimintojen toteutus (lisää kurssi, listaa kurssit jne.). Kun nämä olivat valmiina, tein Lataaja- ja Tallentaja-luokat, kurssien tietojen tallentamisen/parsimisen osalta. Seuraavaksi oli Opintosuunnitelma-luokan vuoro ja viimeisenä aloin rakentamaan graafista käyttöliittymää (Gui-luokka). Samalla kun rakentelin käyttöliittymää, lisäilin aikaisempiin luokkiin lisää toimintoja. Käyttöliittymää varten piti tehdä vielä muutama lisäluokka (ImageComponent, KurssiDialog, KurssiTaulukko, PonnahdusNayttaja, SuoritusTaulukko, TableSorter, Ympyrakaavio), joita en suunnitelmassa ollut ajatellut.

13. Arvio lopputuloksesta

Mielestäni projekti onnistui melko hyvin. Graafinen käyttöliittymä on mielestäni onnistunut ja luokkajakokin onnistui hyvin. Ohjelmakoodista yritin tehdä mahdollisimman selkeää kommentoimalla sitä koko ajan työn edistyessä ja koodista tulikin melko selkeää (itse on tosin aina vaikea arvioida, miten muut omaa koodiaan ymmärtävät).

Ehkä ohjelmaan olisi voinut toteuttaa hieman monimutkaisempia algoritmeja kuten hieman monimutkaisemman opintosuunnitelman automaattisen generoijan. Nyt algoritmit ovat suhteellisen yksinkertaisia (tyyliin listoista kyselyjä jne.).

Seuraavia lisäyksiä ohjelmaan olin suunnitellut, mutten niitä kerennyt/jaksanut toteuttaa:

  • Pääaineen, suunnan ja sivuaineen vaihto
  • Opinnon kurssien ja tietojen muokkaaminen graafisesti
  • Opintosuunnitelman generoija paremmaksi (myös vapaavalintaiset kurssit lisätään automaattisesti, kurssien lisääminen automaattisesti oikeaan periodiin ja voisi määrätä, kuinka monta opintopistettä haluaa suorittaa per periodi)
  • Kurssien listaaminen opinnoittain
  • Valinta uuden ja vanhan tutkintorakenteen välillä (eli suorittaako opiskelija uuden tutkintorakenteen mukaisesti moduuleita vai vanhan tutkintorakenteen mukaisesti suunta, pääaine ja sivuaine)
  • Suorituksen siirtäminen automaattisesti seuraavalla mahdolliselle periodille

14. Viitteet

Materiaaleina käytin lähinnä suomenkielistä Java-ohjelmointi -kirjaa sekä Javan APIa ja englanninkielisiä Java-tutoriaaleja.

15. Liitteet

Alla linkit luokkien lähdekoodeihin:

Lähdekoodi on saatavilla myös yhtenä pakettina. Lisäksi luokista löytyy Javadoc-dokumentaatio.

Suoritettavat ohjelmat

Lähdekooditiedostojen lisäksi projektityö on saatavilla myös valmiiksi käännettynä suoritettavana ohjelmana (pura paketti ja aja ohjelma, älä poista tai siirrä paketissa olevia kansioita):

  • Opintoapuri.exe (Windowsissa kaksoisklikkaamalla aukeava ohjelma)
  • Opintoapuri.jar (Jar-päätteinen ajettava ohjelma, jonka pitäisi toimia kaikissa käyttöjärjestelmissä, joissa on Java-virtuaalikone. Windowsissa ohjelma pitäisi aueta kaksoisklikkaamalla tai valitsemalla hiiren oikealla näppäimellä Avaa sovelluksessa...Java(TM) 2 Platform Standard Edition Binary tai komentoriviltä komennolla java -jar Opintoapuri.jar)

Assistentin kommentteja projektityöstä

  • Dokumentti: Erittäin kattava ja hyvin kirjoitettu dokumentti.
  • Koodin rakenne: Rakenne on hyvä ja toimiva.
  • Koodin laatu: Koodi on siistiä ja runsaasti kommentoitua. Metodit kommentoitu javadoc-formaattiin.
  • Tietorakenteet ja algoritmit: Tietorakenteet ovat järkevästi valittuja. Opintosuunnitelman generointiin käytetty algoritmi ei ole ihan loppuun asti mietitty.
  • Tiedostot: Ok tekstiformaatti.
  • Virheiden käsittely: Virhetapaukset on hyvin käsitelty.
  • Käyttöliittymä: Erittäin toimiva käyttöliittymä, selvästi käyttöliittymäohjelmointi on hallinnassa. Mukavana lisänä opintojen etenemistä kuvaavat piirakkadiagrammit. ImageComponent-luokka olisi jo valmiiksi löytynyt Swingistä nimellä ImageIcon.
  • Testaus: Testauskertomus on vähän suppea, mutta ok.
  • Puuttuvat ominaisuudet: Opintosuunnitelman generointi ei ole ihan valmis. Virheilmoitukset eivät aina ole kovin kuvaavia, mikä olisi ollut helppo korjata. Puutteet on hyvin dokumentoitu, ja osa niistä ei oikeastaan ole kovin oleellisia.
  • Työstä yleisesti: Kokonaisuutena yksi siisteimmin tehdyistä harjoitustöistä. Muutamia pienehköjä ominaisuuksia puuttuu, mutta suunnitelman plussa nostaa vitoseen.

Sivun kommentit