previous next Title Contents Index

2. Kerhon jäsenrekisteri


Mitä tässä luvussa käsitellään?

* tehtävän "analysointi"

* ohjelman vaatimien aputiedostojen sisällön suunnittelu

* ohjelman suunnittelu ohjelman tulosteiden avulla

* suunnitelman korjaus

* tarvittavien algoritmien hahmottaminen

* relaatiotietomalli

2.1 Tehtävän tarkennus

Ohjelman suunnittelu aloitetaan aina tehtävän tarkastelulla. Annettua tehtävää joudutaan usein huomattavasti tarkentamaan.

Olkoon tehtävänä suunnitella kerhon jäsenrekisteri. Onko kerho iso vai pieni? Mitä tietoja jäsenistä talletetaan? Mitä ominaisuuksia rekisteriltä halutaan?

Mikäli sovitaan, että kerho on kohtuullisen pieni (esim. alle 500 jäsentä), ei meidän heti alkuun tarvitse miettiä parhaita mahdollisia hakualgoritmeja eikä tiedon tiivistämistä.

Mitä tietoja jäsenistä tarvitaan?

	- nimi
	- sotu
	- katuosoite
	- postinumero
	- postiosoite
	- kotipuhelin
	- työpuhelin
	- autopuhelin
	- liittymisvuosi
	- tämän vuoden maksetun jäsenmaksun suuruus
	- lisätietoja
	jne...
Mitä ominaisuuksia rekisteriltä halutaan?
	- kerholaisten lisääminen
	- kerholaisten poistaminen
	- tietyn kerholaisen tietojen hakeminen
	- tietyn kerholaisen tietojen muuttaminen
	- postitustarrat postinumerojärjestyksessä 
	- nimilista nimen mukaisessa järjestyksessä
	- lista jäsenmaksua maksamattomista jäsenistä
	jne...

2.2 Työkalun valinta

On varsin selvää, ettei tätä nimenomaista tehtävää kannattaisi nykypäivänä lähteä itse ohjelmoimaan, vaan turvauduttaisiin tietokantaohjelmaan. Joissakin erikoistapauksissa saatetaan vaatia ominaisuuksia, joita tietokantaohjelmasta ei saada. Tällöin työkaluksi valittaisiin lausekieli ja tietokantaohjelmiston aliohjelmakirjasto, joka hoitelee varsinaiset tietokannan ylläpitoon yms. liittyvät toimenpiteet.

Edellinen analyysi on kuitenkin tehtävä työkalusta riippumatta! Esimerkin vuoksi jatkamme tehtävän tutkimista hieman pidemmälle tavoitteena ohjelmoida jäsenrekisteri jollakin lausekielellä.

2.3 Tietorakenteet ja tiedostot

Mikäli työkalun valinnassa on päädytty johonkin lausekieleen, on jossain vaiheessa päätettävä käytettävistä tietorakenteista. Esimerkin tapauksessa meillä on selvästikin joukko yhden henkilön tietoja. Mikäli yhden henkilön tietoa pidetään yhtenä yksikkönä (tietueena), on koko tietorakenne taulukko henkilöiden tiedoista. Taulukko voidaan tarvittaessa toteuttaa myös lineaarisena listana tai jopa puurakenteena. Mikäli kyseessä on pieni rekisteri, mahtuu koko tietorakenne ohjelman ajon aikana muistiin.

Missä tiedot talletetaan kun ohjelma ei ole käynnissä? Tietenkin levyllä tiedostona. Minkä tyyppisenä tiedostona? Tiedoston tyyppinä voisi olla binäärinen tiedosto alkioina henkilötietueet. Tällaisen tiedoston käsittely hätätapauksessa on kuitenkin vaikeata. Varmempi tapa on tallettaa tiedot tekstitiedostoksi, jota tarvittaessa voidaan käsitellä millä tahansa tekstinkäsittelyohjelmalla. Tällöin on lisäksi usein mahdollista käsitellä tiedostoa taulukkolaskentaohjelmalla tai tietokantaohjelmalla ja näin joitakin harvinaisia toimintoja voidaan suorittaa rekisterille vaikkei niitä olisi alunperin edes älytty laittaa ohjelmaan mukaan.

Minkälainen tekstitiedosto? Ehkäpä yhden henkilön tiedot yhdellä rivillä? Miten yhden henkilön eri tiedot erotetaan toisistaan? Mahdollisuuksia on lähinnä kaksi: erotinmerkki tai tietty sarake. Valitaan erotinmerkki. Usein on mukavaa lisäksi laittaa joitakin huomautuksia eli kommentteja tiedostoon. Siis talletustiedoston muoto voisi olla vaikkapa seuraava:

kelmit.dat - ensimmäinen ehdotus tiedostoksi

	; Tässä tiedostossa on KELMIT Ry:n jäsentiedot
	; Kenttien järjestys tiedostossa on seuraava:
	; sukunimi etunimi|sotu|katuosoite|postinumero|postiosoite
	;|kotipuhelin|työpuhelin|autopuhelin|liittymisvuosi|jmaksu|lisätietoja
	Ankka Aku|010245-123U|Ankkakuja 6|12345|ANKKALINNA|12-12324|||1991|50|velkaa Roopelle
	Susi Sepe|020347-123T||12555|Takametsä||||1990|50|jäsen myös kelmien kerhossa
	Ponteva Veli|030455-3333||12555|Takametsä||||50|1989|
Tällaisenaan tiedosto on varsin suttuinen luettavaksi. Vaikka valitsimmekin erotinmerkin erottamaan tietoja toisistaan, voimme silti kirjoittaa vastaavat tiedot allekkain sopimalla, ettei loppuvälilyönneillä ole merkitystä.

kelmit.dat - sarakkeet linjaan

	; Tässä tiedostossa on KELMIT Ry:n jäsentiedot
	; Kenttien järjestys tiedostossa on seuraava:
	; sukunimi etunimi |sotu       |katuosoite  |postinumero|postiosoite|kotipuhelin|työpuhelin|.
	Ankka Aku          |010245-123U|Ankkakuja 6 |12345      |ANKKALINNA |12-12324   |          | 
	Susi Sepe          |020347-123T|            |12555      |Takametsä  |           |          | 
	Ponteva Veli       |030455-3333|            |12555      |Takametsä  |           |          | 
Nyt tiedostoa on helpompi lukea ja tyhjien kenttien jättäminen ei ole vaikeaa. Tiedosto vie kuitenkin levyltä enemmän tilaa kuin ensimmäinen versio. Lisäksi yhden henkilön tiedot eivät mahdu kerralla näyttöön. Onneksi kuitenkin lähes kaikki nykyiset tekstieditorit suostuvat rullaamaan näyttöä myös sivusuunnassa. Mikäli saman henkilön tietoja jaettaisiin eri riveille, tarvitsisi meidän valita vielä tietueen loppumerkki (nytkin se on valittu: rivinvaihto).

2.4 Käyttöohje tai käyttöliittymä

Jatkosuunnittelu on ehkä helpointa tehdä suunnittelemalla ohjelman toimintaa käyttöohjeen tai käyttöliittymän tavoin. Erityisesti graafisella käyttöliittymällä varustettuja ohjelmia suunnitellaan nykytyökaluilla nimenomaan "piirtämällä" käyttäjälle näkyvä käyttöliittymän osa. Tähän osaan sitten lisätään heti tai jälkeenpäin itse toiminnallisuus. Tällaisia työkaluja on esimerkiksi Delphi, Visual Basic ja myös muiden ohjelmointikielten resurssityökalut.

Graafisen käyttöliittymän suunnittelu ja toteutus on kuitenkin jo edistyneempää - ja erityisesti laiteriippuvaa - puuhaa, joten tällä kurssilla täytyy tyytyä "vanhanaikaiseen" keskustelevaan tekstikäyttöliittymään. Jos koodausvaiheessa riittävästi erotetaan käyttöliittymään liittyvä koodi tietorakennetta ylläpitävästä koodista, voidaan ohjelma kohtuullisella työllä muuttaa myös graafisessa käyttöliittymässä toimivaksi.

Suunnittelussa toimitaan käyttäjän ja helppokäyttöisyyden (= myös nopea käyttö, ei aina välttämättä hiiri) ehdoilla.

Ohjelmassa on kahdenlaisia vastauksia. Toisiin riittää painaa pelkkä yksi kirjain tai numero (kuten menut ja K/e tyyppiset valinnat). Mikäli vastaukseen on mahdollista kirjoittaa enemmän kuin yksi merkki, pitää vastaus lopettaa [RET]- näppäimen painamisella (Return, Enter). Jatkossa hoputteilla (prompt) on seuraavat merkitykset

: odotetaan pelkkää yhtä merkkiä. Mikäli vaihtoehdot on lueteltu ja jokin niistä on isolla kirjaimella, valitaan tämä painettaessa [RET]- näppäintä.

> odotetaan 0 - useata merkkiä ja [RET]- näppäintä. Mikäli hoputteen edessä on suluissa jokin arvo, tulee tämä arvo vastauksen arvoksi painettaessa pelkkää [RET]- näppäintä. Mikäli oletusvastaus on epätyhjä ja halutaan antaa vastaukseksi tyhjä merkkijono, painetaan välilyönti ja [RET].

Ohjelman päävalintaan päästään usein vastaamalla pelkkä [RET] uuden kierroksen alussa tai painamalla q[RET] missä tahansa ohjelman kohdassa.

Kun ohjelma käynnistyy, tulostuu näyttöön:

	      ###################################
	      #   J Ä S E N R E K I S T E R I   #
	      #     versio 9.95                 #
	      #     Hannu Hanhi                 #
	      ###################################
	
	Tällä ohjelmalla ylläpidetään kerhon jäsenrekisteriä.
	Anna kerhon nimi>_
Kerhon tiedot on talletettu vaikkapa tiedostoon nimi.DAT. Näin voimme ylläpitää samalla ohjelmalla useiden eri kerhojen tietoja. Mitäpä jos tiedostoa ei ole? Tällöin voi syynä olla kirjoitusvirhe tai se, ettei rekisteriä ole vielä edes aloitettu! Miten ohjelman tulee tällöin menetellä?
	Tällä ohjelmalla ylläpidetään kerhon jäsenrekisteriä.
	Anna kerhon nimi>KERMIT[RET]
	Kerhon KERMIT tietoja ei ole!  
	Luodaanko tiedot (K/e):e
	Anna kerhon nimi>KELMIT[RET]
	Odota hetki, luetaan tietoja...
	
	Jäsenrekisteri
	==============
	
	Kerhossa KELMIT on 52 jäsentä.
	
	Valitse:
	   0  = lopetus
	   1  = lisää uusi jäsen
	   2  = etsi jäsenen tiedot
	   3  = tulosteet
	   4  = tietojen korjailu
	   :_

Edellä on edetty siihen saakka, kunnes ohjelmassa on päädytty päävalikkoon (main menu). Seuraavaksi voimme lähteä tarkastelemaan eri alakohtien toimintaa. Näissä eri erikoistapaukset on otettava huomioon:

2.4.1 Lisää uusi jäsen

	1. Uuden jäsenen lisäys
	=======================
	Jäseniä on nyt 52.
	Anna uusi nimi muodossa sukunimi etunimi etunimi
	Jäsenen nimi      ()            >Ankka Aku[RET]
	Rekisterissä on jo jäsen Aku Ankka!  Mikäli haluat muuttaa
	hänen tietojaan, valitse tietojen korjailu päävalikosta!
	Jäsenen nimi      ()            >ANKKA TUPU[RET]
	Sotu              ()            >012356-1257[RET]
	Sotu mieletön tai tarkistusmerkki väärin (N)!
	Sotu              (012356-125N) >010356-125J[RET]
	Katuosoite        ()            >Ankkakuja 6[RET]
	Postinumero       (12345)       >[RET]
	Postiosoite       (ANKKALINNA)  >[RET]
	Kotipuhelin       ()            >12-12324[RET]
	Työpuhelin        ()            >[RET]
	Autopuhelin       ()            >[RET]
	Liittymisvuosi    (91)          >91[RET]
	Jäsenmaksu mk     (50)          >10[RET]
	Lisätietoja       ()            >Aku Ankan veljenpoika[RET]
	
	Lisätäänkö 
	  Ankka Tupu 010356-125J
	  Ankkakuja 6 12345 ANKKALINNA
	  k: 12-12324 t: a:
	  Liittynyt -91.  Jäsenmaksu 10 mk.
	  Aku Ankan veljenpoika
	:k
	
	Jäseniä on nyt 53.
	
	Anna uusi nimi muodossa sukunimi etunimi etunimi
	Jäsenen nimi      ()            >[RET]
	
	Jäsenrekisteri
	==============
	
	Kerhossa KELMIT on 53 jäsentä.
	
	Valitse:
	   0  = lopetus
	   1  = lisää uusi jäsen
	   2  = etsi jäsenen tiedot
	...
Edellä on suluissa esitetty oletusarvo, joka tulee kentän arvoksi, mikäli painetaan pelkkä [RET]. Mikäli oletusarvon tilalle halutaan vaikkapa tyhjä merkkijono, vastataan välilyönti ja [RET]. Näin voidaan nopeuttaa tiettyjen samojen asioiden syöttöä. Oletusarvo voidaan antaa joko ohjelmasta väkisin (kuten tyhjä sotuksi) tai se voidaan ottaa edellisen syötön perusteella.

2.4.2 Etsi jäsenen tiedot

Tietoa voidaan hakea usealla eri tavalla. Voidaan haluta etsiä nimellä, osoitteella tai jopa puhelinnumerolla. Myös lisätietokentästä voidaan haluta etsiä tiettyä sanaa.

Siis aluksi pitää valita minkä kentän mukaan haetaan. Kun kenttä on selvitetty, voi olla mielekästä voida käyttää myös jokerimerkkejä (esim ? ja *, vrt. MS-DOS.

	2. Etsi jäsenen tiedot
	======================
	
	  Nykyinen henkilö:
	
	  Ankka Lupu 010356-127L
	  Ankkakuja 6 12345 ANKKALINNA
	  k: 12-12324 t: a:
	  Liittynyt -91.  Jäsenmaksu 10 mk.
	  Aku Ankan veljenpoika, sudenpentu
	
	Valitse kenttä jonka mukaan etsitään (?=kenttälista uudel.) :?
	
	  1 = nimi
	  2 = sotu 
	  3 = katuosoite     
	  4 = postinumero
	  5 = postiosoite
	  6 = kotipuhelin
	  7 = työpuhelin     
	  8 = autopuhelin    
	  9 = liittymisvuosi 
	  A = jäsenmaksu mk  
	  B = lisätietoja    
	
	Valitse kenttä jonka mukaan etsitään (?=kenttälista uudel.) :1
	Jäsenen nimi      (Ankka Lupu)  >*ANKKA*[RET]
	Tähän täsmää 3 jäsentä:
	
	  Ankka Aku 010245-123U
	  Ankkakuja 6 12345 ANKKALINNA
	  k: 12-12324 t: a:
	  Liittynyt -91.  Jäsenmaksu 50 mk.
	  velkaa Roopelle
	
	Lisää (K/e):[RET]
	
	  Ankka Lupu 010356-127L
	  Ankkakuja 6 12345 ANKKALINNA
	  k: 12-12324 t: a:
	  Liittynyt -91.  Jäsenmaksu 10 mk.
	  Aku Ankan veljenpoika, sudenpentu
	
	Lisää: (K/e):e
	
	2. Etsi jäsenen tiedot
	======================
	
	Valitse kenttä jonka mukaan etsitään (?=kenttälista uudel.) :[RET]
Korjailua ja muuta varten on mukaavaa, että viimeksi löydetyn henkilön tiedot jäävät muistiin. Näin esimerkiksi korjailu tai poisto voidaan tehdä suoraan tälle henkilölle.

2.4.3 Tulosteet

Tulosteita varten voisi tulla menu siitä, mitä tulostetaan. Lisäksi voisi olla kysymys siitä, millä ehdoilla tulostus tehdään (jäsenmaksu maksamatta jne.) sekä tulostusjärjestys. Tulostusjärjestys on tärkeä, sillä esimerkiksi postitusta varten lehdet yms. pitää lajitella postin antamien ohjeiden mukaisesti postinumeroittain nippuihin, jotka sitten menevät tietylle postialueelle. Jäsenrekisteriä varten taas aakkosjärjestetty lista on kätevin.

Tulostuskohdan suunnittelu jätetään lukijalle harjoitustehtäväksi. Tulosteiden ulkonäkö kannattaa kuitenkin suunnitella tarkasti, koska tämä on muille kerholaisille näkyvin osa ohjelmastamme!

Tehtävä 2.1 Tulosteet

Suunnittele tulostusmenu ja kunkin kohdan alta mahdollisesti saatavat kysymykset sekä tulosteiden ulkonäkö.

2.4.4 Tietojen korjailu

	4.  Tietojen korjailu
	=====================
	
	  Korjailtava henkilö:
	
	  Ankka Lupu 010356-127L
	  Ankkakuja 6 12345 ANKKALINNA
	  k: 12-12324 t: a:
	  Liittynyt -91.  Jäsenmaksu 10 mk.
	  Aku Ankan veljenpoika, sudenpentu
	
	Valitse kenttä jonka mukaan etsitään (?=kenttälista uudel.) 
	tai poisto (P) tai korjailu (K) :1
	
	Jäsenen nimi      (Ankka Lupu)  >*aku*[RET]
	Tähän täsmää 1 jäsentä:
	
	  Ankka Aku 010245-123U
	  Ankkakuja 6 12345 ANKKALINNA
	  k: 12-12324 t: a:
	  Liittynyt -91.  Jäsenmaksu 50 mk.
	  velkaa Roopelle
	
	Valitse kenttä jonka mukaan etsitään (?=kenttälista uudel.)
	tai poisto (P) tai korjailu (K) :p
	
	Haluatko todellakin poistaa jäsenen Ankka Aku (k/E):e
	
	Valitse kenttä jonka mukaan etsitään (?=kenttälista uudel.) 
	tai poisto (P) tai korjailu (K) :k
	
	Jäsenen nimi      (Ankka Aku)   >[RET]
	Sotu              (010245-123U) >[RET]
	Katuosoite        (Ankkakuja 6) >Ankkakuja 13[RET]
	Postinumero       (12345)       >[RET]
	Postiosoite       (ANKKALINNA)  >[RET]
	Kotipuhelin       (12-12324)    >12-12325[RET]
	Työpuhelin        ()            >12-33333[RET]
	Autopuhelin       ()            >[RET]
	Liittymisvuosi    (91)          >[RET]
	Jäsenmaksu mk     (50)          >[RET]
	Lisätietoja       (velkaa Roopelle) >[RET]
	
	  Ankka Aku 010245-123U
	  Ankkakuja 13 12345 ANKKALINNA
	  k: 12-12325 t: 12-33333 a:
	  Liittynyt -91.  Jäsenmaksu 50 mk.
	  velkaa Roopelle
	
	Valitse kenttä jonka mukaan etsitään (?=kenttälista uudel.) 
	tai poisto (P) tai korjailu (K) :[RET]
Huomattakoon, että edellä LUPU ANKKA jäi vielä asumaan osoitteeseen Ankkakuja 6. Tietysti ohjelma voitaisiin tehdä myös siten, että joidenkin tiettyjen arvojen muuttaminen muuttaisi haluttaessa myös muita (esim. kirjoitettu sama osoite).

2.4.5 Lopetus

Ohjelman lopetuksessa tulee huolehtia siitä, että ohjelman aikana mahdollisesti rekisteriin tehdyt muutokset tulevat talletetuksi. Tämä voidaan tehdä automaattisesti tai talletus voidaan varmistaa käyttäjältä. Automaattisen talletuksen tapauksessa alkuperäinen tiedosto on ehkä syytä tallettaa eri nimelle.
	      ###################################
	      #   J Ä S E N R E K I S T E R I   #
	      #     versio 9.95                 #
	      #     Hannu Hanhi                 #
	      ###################################
	
	
	Tiedot talletettu tiedostoon KELMIT.DAT
	Vanhat tiedot tiedostossa    KELMIT.BAK
	
	  KIITOS KÄYTÖSTÄ JA TERVETULOA UUDELLEEN

2.5 Käyttöohjeen testaus

Kirjoitettu käyttöohje kannattaa antaa jollekin luotettavalle henkilölle "apinatestiin". Onko toimintoja riittävästi? Keksitäänkö erikoistapauksia, joista saattaisi seurata hankaluuksia?

Miksi jäsenen tietojen etsintä ja korjailu ovat eri paikoissa? Turvallisuussyistä!

2.5.1 Testaus

Annetaanpa käyttöohje vaikkapa kerhon sihteerin testattavaksi. Hänelle on juuri vuodenvaihteessa tullut iso kasa pankkisiirtokuitteja uuden vuoden jäsenmaksujen maksamisesta. Niinpä seuraakin ehkä keskustelu: Sihteeri: Miten jäsenmaksut korjataan. Ensin kaikki viimevuotiset pitää poistaa. Jaa ehkä jos joku on ainaisjäsen, niin hänen merkintäänsä ei poisteta. No muilta kuitenkin. Sitten pitäisi nämä kuitit saada naputeltua sinne!

Ohjelmoija: No poisto ensiksi. Valitse 4 eli korjailu. Sitten valitse 1 Jäsenen nimi ja vastaa ensimmäisen jäsenen nimi. Kun se löytyy, niin paina K niinkuin korjailu ja sitten vain RET kunnes olet jäsenmaksun kohdalla ja sitten välilyönti ja RET jäsenmaksuun. Sitten taas 1 Jäsenen nimi jne. Helppoa!

Sihteeri: Tuohan vie AINAKIN vuoden!!! MINÄ KÄYTÄN EDELLEEN VANHAA käsikirjanpitoani. Tästä vaan kumilla vanha pois ja uusi tieto tilalle...

Ohjelmoija: Öh, tuota mutta kun minä...

2.5.2 Korjaus

Siis parasta mennä takaisin miettimään. Onneksi itse ohjelmaa ei ole ehditty kirjoittamaan. Jäsenmaksut?

Miten jäsenmaksukentän käyttö? Ehkä tämä kenttä pitää säilyttää tiedoksi siitä, paljonko henkilön pitäisi maksaa jäsenmaksua. Tarvitsemme siis uuden kentän:

	Maksettu maksu    (10)          >
Ainais- ja kunniajäsenet hoidetaan siten, että heidän jäsenmaksukseen, joka pitäisi maksaa, annetaan vaikkapa 0 mk.

Lisäksi meille ilmiselvät asiat eivät aina olleetkaan sihteerille selviä. Ohjelmaamme täytynee lisätä myös avustus.

Lisätään kaksi uutta valintaa päävalikkoon:

	...
	Valitse:
	   ?  = avustus
	   0  = lopetus
	   1  = lisää uusi jäsen
	   2  = etsi jäsenen tiedot
	   3  = tulosteet
	   4  = tietojen korjailu
	   5  = päivitä jäsenmaksuja
	   :5
	
	5. Päivitä jäsenmaksuja
	=======================
	
	Valitse:
	   ?  = avustus
	   0  = takaisin päävalintaan
	   1  = poista kaikki edellisen vuoden maksut
	   2  = kysy maksettu maksu nimen mukaan
	   :1
	
	Poistetaan kaikki edellisen vuoden jäsenmaksut!
	Poistetaan siis kaikki maksetut jäsenmaksut (K/e):K
	Odota hetki...  Jäsenmaksut poistettu!
	
	Valitse:
	   ?  = avustus
	   0  = takaisin päävalintaan
	   1  = poista kaikki edellisen vuoden maksut
	   2  = kysy maksettu maksu nimen mukaan
	   :2
	
	Muutetaan maksettuja jäsenmaksuja!
	==================================
	
	Jos haluat kaikki jäsenet, anna *
	Kysely loppuu, mikäli annat maksuksi  q
	Jäsenen nimi      ()            >*[RET]
	
	  Ankka Aku 010245-123U
	  Ankkakuja 13 12345 ANKKALINNA
	  k: 12-12325 t: 12-33333 a:
	  Liittynyt -91.  Jäsenmaksu 50 mk.  Maksettu mk.
	  velkaa Roopelle
	Maksettu maksu mk ()            >[RET]
	
	  Ankka Lupu 010356-127L
	  c/o Aku Ankka (Ankkakuja 13 12345 ANKKALINNA)
	  k: 12-12324 t: a:
	  Liittynyt -91.  Jäsenmaksu 10 mk.  Maksettu mk.
	  Aku Ankan veljenpoika, sudenpentu
	Maksettu maksu    ()            >10[RET]
	... Jatkuu näin kunnes kaikki käyty läpi ...
	... Tai vastataan ...
	Maksettu maksu mk ()            >q[RET]
	
	Jäsenen nimi      ()            >*aku*[RET]
	  Ankka Aku 010245-123U
	  Ankkakuja 13 12345 ANKKALINNA
	  k: 12-12324 t: a:
	  Liittynyt -91.  Jäsenmaksu 50 mk.  Maksettu mk.
	  velkaa Roopelle
	Maksettu maksu    ()            >40[RET]
	Pitäisi maksaa 50 mk ja on maksanut 40 mk.  
	Onko oikein (K/e):e
	Maksettu maksu mk ()            >50[RET]
	
	Jäsenen nimi      ()            >[RET]
	
	Valitse:
	   ?  = avustus
	   0  = takaisin päävalintaan
	   1  = poista kaikki edellisen vuoden maksut
	   2  = kysy maksettu maksu nimen mukaan
	   :0
	...

2.5.3 Muita korjauksia

Käyttäjällä saattaa tulla vaikeuksia myös kesken jonkin kysymyksen. Tällöin voisi olla hyvä, että käyttäjä voi painaa ?- merkkiä ja saada avustusta siitä, mitä tähän kohti pitäisi syöttää (sisältöriippuva avustus, context sensitive help).

Jäsenmaksun päivittämisessä jokerimerkin käyttö tuntui varsin kätevältä tavalta saada joko yksi tai useampi henkilö (tai vaikkapa kaikki) päivitettäväksi.

Samaa ajatusta voitaisiin täydentää myös muuhun päivittämiseen. Muutetaankin korjailussa esiintynyt kysymys

	Valitse kenttä jonka mukaan etsitään (?=kenttälista uudel.)
	tai poisto (P) tai korjailu (K) :
muotoon
	Valitse kenttä jonka mukaan etsitään (?=kenttälista uudel.),
	poisto (P), korjailu (K), seuraava (+), edellinen (-):
silloin, kun hakuehtoon täsmääviä on löytynyt useita. Tekstit seuraava ja edellinen voidaan varmaankin jättää pois, jos seuraavaa tai edellistä ei ole.

Kenttälistaan hakuehdossa voitaisiin lisätä lisäkohta, jossa kaikille kentille voidaan antaa ehto (ja/tai):

	  1 = nimi
	...
	  9 = liittymisvuosi 
	  A = jäsenmaksu mk  
	  B = maksettu maksu mk
	  C = lisätietoja    
	  & = JA ehto kaikille kentille
	  | = TAI ehto kaikille kentille
	
	Valitse kenttä jonka mukaan etsitään (?=kenttälista uudel.):&
	
	Kirjoita niihin kenttiin ehto, joiden mukaan haluat etsiä.
	== tarkoittaa, että kentän TÄYTYY olla tyhjä.
	Jäsenen nimi      ()            >*ankka*[RET]
	Sotu              ()            >[RET]
	Katuosoite        ()            >[RET]
	Postinumero       ()            >[RET]
	Postiosoite       ()            >[RET]
	Kotipuhelin       ()            >[RET]
	Työpuhelin        ()            >[RET]
	Autopuhelin       ()            >[RET]
	Liittymisvuosi    ()            >[RET]
	Jäsenmaksu mk     ()            >[RET]
	Maksettu maksu mk ()            >==[RET]
	Lisätietoja       ()            >[RET]
	
	Tähän täsmää 1 jäsentä:
	
	  Ankka Tupu 010356-125J
	  Ankkakuja 6 12345 ANKKALINNA
	  k: 12-12324 t: a:
	  Liittynyt -91.  Jäsenmaksu 10 mk. Maksettu mk.
	  Aku Ankan veljenpoika
	...
Edellä siis etsittiin kaikkia niitä Ankkoja, joilla maksettu maksu on tyhjä. Näin sihteeri voisi aina tutkia kenellä maksut on maksamatta (tässä tapauksessa erityisesti Ankoista). Hakuehtoihin voitaisiin vielä liittää epäyhtälöt:
	<    <=    >   >=    ==   !=
Siis hakuehto voisi olla esimerkiksi
	Jäsenen nimi      ()            >!=*ankka*[RET]
	Sotu              ()            >[RET]
	...
	Jäsenmaksu mk     ()            ><30[RET]
	Maksettu maksu mk ()            >==[RET]
	Lisätietoja       ()            >[RET]
Eli etsitään niitä jäseniä, joiden nimi EI OLE *ankka* ja joiden jäsenmaksu on alle 30 sekä maksettu maksu on tyhjä.

Samalla tietojen etsimisessä kysymys

	Lisää (K/e):[RET]
voitaisiin muuttaa selaukseksi:
	Valitse kenttä jonka mukaan etsitään (?=kenttälista uudel.),
	seuraava (+), edellinen (-):
Kerhon nimi saattaa olla varsin pitkä. Sen antaminen aina ohjelman käynnistämisen yhteydessä voi olla työlästä. Siksi käynnistämisessä kannattaakin antaa vain lyhenne, jolla tiedosto on talletettu. Varsinainen nimi täytyy tallettaa jonnekin muualle. Minne?

Nimi voitaisiin tallettaa vaikkapa jäsenrekisteritiedoston ensimmäiselle riville:

kelmit.dat - kerhon nimikin talteen

	Kelmien kerho ry
	; Kenttien järjestys tiedostossa on seuraava:
	; sukunimi etunimi |sotu       |katuosoite  |postinumero|postiosoite|kotipuhelin|työpuhelin|
	Ankka Aku          |010245-123U|Ankkakuja 6 |12345      |ANKKALINNA |12-12324   |          | 
	Susi Sepe          |020347-123T|            |12555      |Takametsä  |           |          | 
	Ponteva Veli       |030455-3333|            |12555      |Takametsä  |           |          | 
Kerhon nimi kysytään käyttäjältä uutta tiedostoa luotaessa.

Jos halutaan vielä suurempaa yhteensopivuutta valmiiden tietokantaohjelmien kanssa, voidaan kerhon nimi tallettaa erilliseen tiedostoon muiden kerhoon liittyvien lisätietojen kanssa. Esimerkiksi jos jäsenet on tiedostossa kelmit.dat, voisi lisätiedot olla tiedostossa kelmit.opt. Tällöin myös kommentit (;) kannattaa jättää pois tiedostosta ja tiedoston ensimmäinen rivi on kenttien nimiä kuvaava rivi.

kelmit.dat - yhteensopivuus muihin ohjlemiin

	nimi               |sotu       |katuosoite  |postinumero|postiosoite|kotipuhelin|työpuhelin|
	Ankka Aku          |010245-123U|Ankkakuja 6 |12345      |ANKKALINNA |12-12324   |          | 
	Susi Sepe          |020347-123T|            |12555      |Takametsä  |           |          | 
	Ponteva Veli       |030455-3333|            |12555      |Takametsä  |           |          | 

kelmit.opt - yleiset tiedot tänne

	[Tiedot]
	nimi=Kelmien kerho ry
	maxjaseniä=100

2.5.4 Uusi testaus

Koska käyttöohjeemme on tietenkin kirjoitettu tekstinkäsittelyohjelmalla (tai ohjelmaeditorilla), on muutokset helppo tehdä. Menemme uudelleen sihteerin luokse uudistetun käyttöohjeen kanssa ja pyydämme jos hän armeliaasti vielä kerran suostuisi katsomaan sitä.

Paranneltavaa saattaa löytyä lisää nyt kun kiinnostus ehkä herää. Korjaamme selvät kohdat mutta joistakin asioista täytyy neuvotella ja ainakin tinkiä ettei niitä ehkä toteuteta ohjelman ensimmäiseen versioon.

Yksi selvä ongelma ilmenee. Entä jos lisäyksessä todella on kaksi samannimistä jäsentä? Homma täytynee korjata seuraavasti:

	Jäsenen nimi      ()            >Ankka Aku[RET]
	Rekisterissä on jo jäsen Aku Ankka!  Mikäli haluat muuttaa
	hänen tietojaan, valitse tietojen korjailu päävalikosta!
	Lisätäänkö sama nimi (l) vai kysytäänkö toinen nimi (T):T
	Jäsenen nimi      ()            >ANKKA TUPU[RET]
Jatkamme testauskierrosta kunnes potentiaaliset käyttäjät on saatu tyytyväiseksi.

2.6 Tarvittavien algoritmien hahmottaminen

Nyt olemme selvillä ohjelman toiminnasta. Edellisestä käyttöohjeesta voimme etsiä mitä työkaluja (aliohjelmia) tarvitsemme ohjelman toteutuksessa. Ainakin seuraavat tulevat helposti mieleen:

2.6.1 Ylemmän tason aliohjelmat

1.
tiedoston lukeminen
2.
tiedoston tallettaminen
3.
henkilön tietojen kysyminen päätteeltä
4.
tiedoston lajittelu haluttuun järjestykseen
5.
tiedon etsiminen tiedostosta tietyllä hakuehdolla
6.
uuden henkilön lisääminen tiedostoon
7.
henkilön poistaminen tiedostosta

2.6.2 Alemman tason aliohjelmat

Mikäli tutkimme yo. palasia tarkemmin, tarvitsemme ehkä seuraavia pienempiä ohjelman palasia (apualiohjelmia):
1.
yhden merkin vastauksen lukeminen mahdollisen oletusarvon kanssa
2.
merkkijonon lukeminen päätteeltä siten, että sille voidaan jättää oletusarvo
3.
pitkän merkkijonon pilkkominen osamerkkijonoihin annetun merkin kohdalta
4.
loppuvälilyöntien poistaminen merkkijonosta
5.
isojen ja pienien kirjainten muuttaminen merkkijonossa Esim:
	AKU ANKKA  ->  Aku Ankka
	aku ankka  ->  Aku Ankka
	aKU ANkKa  ->  AKU ANKKA
6.
sotun oikeellisuuden tarkistus
7.
ovatko merkkijonot "*aku*" ja "AKU ANKKA" samoja?

2.6.3 Ohjelman yhteiset osat

Kannattaa myös etsiä onko ohjelmassa samanlaisina toistuvia osia. Edellä meillä selvästikin tiedon haku on samanlainen sekä etsimis- että korjailukohdassa. Samoin henkilön tietojen luku on samanlainen sekä lisäämisessä että korjailussa. Yhden henkilön tietojen tulostaminen näytölle esiintyy useammassa kohdassa.

Mikäli löytyy likipitäen samanlaisuuksia, kannattaa harkita voidaanko ne käyttämisen yksinkertaistamiseksi ja/tai ohjelmoinnin helpottamiseksi muuttaa samanlaisiksi. Mikäli voidaan, korjataan äkkiä käyttöohjetta tältä osin.

2.7 Ikkunoinnit ja muut hienostelut

Ohjelma voitaisiin suunnitella myös nykyaikaisen ikkunoidusti toimivan käyttöliittymän mukaiseksi. Kuten edellä todettiin, tämä on kuitenkin ohjelmoinnin oppimisen tässä vaiheessa liian työlästä ja tähän paneudutaan vasta myöhemmillä kursseilla.

Tässäkin ohjelmassa korjailua voitaisiin parantaa siten, että meillä olisi käytössä aliohjelma, jolle korjailtava merkkijono vietäisiin parametrina. Palautuksena tulisi korjattu merkkijono ja korjailun aikana toimisivat nuolinäppäimet yms. hienoudet. Tosin suurtakaan muutosta ohjelmaan ei tarvitse tehdä mikäli em. aliohjelman tilalla käytämme aluksi vain merkkijonon lukemiseen kykenevää aliohjelmaa. Myöhemmin tätä voitaisiin parantaa.

Menut voisivat olla nykytyyliin alasvetovalikoita, mutta aluksi meille riittää vallan hyvin käyttöohjeessa esitetyn kaltainen "näyttö tyhjäksi ja uusi menu ruutuun" - tyyli. Myös hiirtä voitaisiin käyttää, mutta jälleen ohjelmointityö kasvaisi vastaavasti.

Hakuehdot voisivat olla monipuolisempia ja niille voitaisiin yrittää keksiä jokin hienompi menetelmä. Esimerkiksi tarvitsisi hakea seuraavilla ehdoilla

	nimi on "*ankka*" tai jäsenmaksu on "<50"
	postiosoite "ankka*" ja lisätiedoissa "*sudenpentu*"
Tätä varten hakemiseen voitaisiin kehitellä vaikkapa seuraavanlainen kieli:
	Hakuehto >(nimi=*ankka*) || (jmaksu<50)[RET]
	...
	Hakuehto >(postiosoite=ankka*) && (lisätiedot=*sudenpentu*)[RET]
Saattaa tulla myös tarve lisätä uusia kenttiä henkilön tietoihin. Tämä on hallittavissa huolellisella ohjelman suunnittelulla, jossa käytettyjen kenttien määrä ja nimet esiintyisivät vain yhdessä paikassa ohjelmaa.

Kun näitä haluttuja lisäominaisuuksia silmäillään, ei ole ihme että on kehitetty tietokantaohjelmia; eli halutut ominaisuudet tarvitaan lähes jokaisessa vastaavassa sovelluksessa. Hieman muuttamalla oman ohjelmamme toimintaa, voisimme saada siitäkin yleiskäyttöisen tietokantaohjelman, mutta jätettäköön tämäkin lukijalle harjoitustehtäväksi.

Etsimisissä voisi olla oletuksena lisätä * kummallekin puolelle etsittävää jonoa, jolloin kun nimeen vastataan

	aku
täydennetään tämä muotoon
	*AKU*
ja näin löydetään Ankka Aku.

2.8 Koodaus ohjelmointikielelle

Seuraava vaihe olisi suunnitelman koodaaminen valitulle ohjelmointikielelle. Voisimme kirjoittaa aluksi löytämiämme alimman tason aliohjelmia (BOTTOM-UP- suunnittelu) ja testata ne toimiviksi. Voisimme myös kirjoittaa pääohjelman ja tyhjiä aliohjelmia testataksemme ohjelman rungon (TOP-DOWN). Menujen alavalinnat voitaisiin laittaa vain sanomaan:
	TOIMINTAA EI OLE VIELÄ TOTEUTETTU!
Emme kuitenkaan osaa vielä riittävästi ohjelmointikieltä, jotta voisimme aloittaa koodauksen. Huomattakoon, ettei ylläolevassa suunnitelmassa ole missään kohti vedottu käytettävään ohjelmointikieleen. Palaamme myöhemmin takaisin ohjelman osien koodaamiseen.

2.9 Varautuminen tulevaan, eli relaatiotietomalli

Vaikka sihteerimme ei juuri nyt huomannutkaan, saattaa hän tulevaisuudessa esimerkiksi kysyä miten rekisterillä pidettäisiin yllä tietoja jäsenten harrastuksista. Mietitäänpä?

Ensin miten harrastukset muuttaisivat tiedostomuotoamme?

2.9.1 Kaikki samassa tietueessa

Eräs mahdollisuus olisi lisätä kunkin rivin loppuun jollakin erotinmerkillä harrastukset:

kelmit.dat - harrasteet samalle riville

	Kelmien kerho ry
	; Kenttien järjestys tiedostossa on seuraava:
	; sukunimi etunimi |sotu       |...|harrastukset
	Ankka Aku          |010245-123U|...|kalastus,laiskottelu,työn pakoilu 
	Susi Sepe          |020347-123T|...|possujen jahtaaminen,kelmien kerho
	Ponteva Veli       |030455-3333|...|susiansojen rakentaminen
Ratkaisu toimisi tietyissä erityistapauksissa. Ongelmia tulisi esimerkiksi jos pitäisi kuhunkin harrastukseen liittää esimerkiksi harrastuksen aloitusvuosi, viikottain harrastukseen käytetty tuntimäärä jne.

2.9.2 Erimalliset tietueet

Edellinen ongelma ratkeaisi esimerkiksi laittamalla henkilön tietojen rivin perään jollakin tavalla eroavia rivejä, joilla harrastuksen on lueteltu:

kelmit.dat - harrasteet omalle riville

	Kelmien kerho ry
	; Kenttien järjestys tiedostossa on seuraava:
	; sukunimi etunimi |sotu       |katuosoite  |postinumero|postiosoite|kotipuhelin|työpuhelin|
	Ankka Aku          |010245-123U|Ankkakuja 6 |12345      |ANKKALINNA |12-12324   |          | 
	- kalastus                 | 1955 | 20
	- laiskottelu              | 1950 | 20
	- työn pakoilu             | 1952 | 40
	Susi Sepe          |020347-123T|            |12555      |Takametsä  |           |          | 
	- possujen jahtaaminen     | 1954 | 20
	- kelmien kerho            | 1962 |  2
	Ponteva Veli       |030455-3333|            |12555      |Takametsä  |           |          | 
	- susiansojen rakentaminen | 1956 | 15
Ratkaisu olisi aivan hyvä ja tämän ratkaisun valitsemiseksi meidän ei tarvitsisi tehdä mitään muutoksia tiedostomuotoomme vielä tässä vaiheessa.

Huono puoli on kuitenkin se, että tämän muotoisen tiedoston siirrettävyys muihin järjestelmiin on varsin huono.

2.9.3 Relaatiomalli

Suurin osa tämän hetken valmiista järjestelmistä käyttää relaatiotietokantamallia. Tämä tarkoittaa sitä, että koko tietokanta koostuu pienistä tauluista, jossa kukin rivi (=tietue) on samaa muotoa. Eri taulujen välillä tiedot yhdistetään yksikäsitteisten avainkenttien avulla. Meidän esimerkissämme kelmit.dat olisi yksi tällaisen taulu ja sosiaaliturvatunnus kelpaisi yhdistäväksi avaimeksi (relaatioksi).

Kuitenkin sosiaaliturvatunnus on varsin pitkä kirjoittaa ja välttämättä sitä ei saada kaikilta. Jos tällainen pelko on olemassa, täytyy avain luoda itse. Itse ohjelman käyttäjän ei tarvitse tietää mitään tästä uudesta muutoksesta, vaan ohjelma voi itse generoida avaimet ja käyttää niitä sisäisesti.

Valitaan vaikkapa juoksevasti generoituva numero. Jos jäseniä poistetaan jää ko. jäsenen numero vapaaksi eikä sitä yritetäkään enää käyttää. Uuden jäsenen numero olisi sitten aina suurin jäsenen numero +1.

kelmit.dat - relaatiokannan päätaulu

	Kelmien kerho ry
	; Kenttien järjestys tiedostossa on seuraava:
	;id|sukunimi etunimi   |sotu       |katuosoite  |postinumero|postiosoite|kotipuhelin|työpuhelin|
	1  |Ankka Aku          |010245-123U|Ankkakuja 6 |12345      |ANKKALINNA |12-12324   |          | 
	2  |Susi Sepe          |020347-123T|            |12555      |Takametsä  |           |          | 
	4  |Ponteva Veli       |030455-3333|            |12555      |Takametsä  |           |          | 
Harrastukset kirjoitetaan toiseen tiedostoon, jossa tunnusnumerolla ilmaistaan kuka harrastaa mitäkin harrastusta.

harrastu.dat - harrasteet relaation avulla

	id|harrastus                |aloit |viikossa
	1 |kalastus                 | 1955 | 20
	1 |laiskottelu              | 1950 | 20
	1 |työn pakoilu             | 1952 | 40
	2 |possujen jahtaaminen     | 1954 | 20
	2 |kelmien kerho            | 1962 |  2
	4 |susiansojen rakentaminen | 1956 | 15

Nyt esimerkiksi kysymykseen "Mitä Sepe Susi harrastaa" saataisiin vastus etsimällä ensin Sepe Suden tunnus (2) tiedostosta kelmit.dat. Sitten etsittäisiin ja tulostettaisiin kaikki rivit joissa tunnus on 2 tiedostosta harrastu.dat.

Myös vastaus kysymykseen "Ketkä harrastavat laiskottelua" löytyisi suhteellisen helposti.

Tämä ratkaisu vaatii muutoksen tiedostomuotoomme jo suunnitelman tässä vaiheessa, mutta toisaalta mikäli ratkaisu valitaan, voidaan sen ansiosta lisätä jatkossa vastaavia "monimutkaisia" kenttiä rajattomasti tekemällä kullekin oma "taulu".

Valitsemmekin siis tämän ratkaisun, eli annamme kullekin jäsenelle tunnusnumeron heti alusta pitäen. Itse ohjelman käyttösuunnitelmaan ei tässä vaiheessa tarvita muutoksia.

Tehtävä 2.2 Ketkä harrastavat?

Kirjoita algoritmi joka relaatiomallin tapauksessa vastaa kysymykseen "Ketkä harrastavat harrastusta X".

Tehtävä 2.3 Mikä on tilaa säästävin talletusmuoto

Laske mikä edellä esitetyistä kolmesta vaihtoehdosta on tilaa säästävin kun rivinvaihtomerkin lasketaan vievän yhden merkin verran tilaa ja välilyönnit "unohdetaan".


previous next Title Contents Index