Tämä materiaali on lisensoitu Creative Commons BY-NC-SA-lisenssillä, joten voit käyttää ja levittää sitä vapaasti, kunhan alkuperäisten tekijöiden nimiä ei poisteta. Jos teet muutoksia materiaaliin ja haluat levittää muunneltua versiota, se täytyy lisensoida samanlaisella vapaalla lisenssillä. Materiaalien käyttö kaupalliseen tarkoitukseen on ilman erillistä lupaa kielletty.
Tekijät: Arto Vihavainen ja Matti Luukkainen
Tässä osallistut kokeellisessa psykologiassa käytettyyn tehtävänvaihtotestiin, missä tutkitaan aivojen mukautumista kahden tai useamman samanaikaisen tehtävän suorittamiseen. Tavoitteenamme on selvittää vaikuttaako ohjelmointi aivojen kykyyn hoitaa useampia samanaikaisia tehtäviä. Tämä testi tehdään useamman kerran kurssin aikana.
Käytössä olevassa testiohjelmassa on neljä osaa. Ensimmäisessä osassa mitataan reaktioaikaa, toisessa osassa parittoman (odd) ja parillisen (even) luvun tunnistamista, kolmannessa osassa konsonantin (consonant) ja vokaalin (vowel) tunnistamista, ja viimeisessä osassa yhdistetään osat kaksi ja kolme. Näet jokaisen osion jälkeen edellisen osion tulokset.
Testin tulokset tulevat vain tutkimuskäyttöön, eikä mahdollisesti raportoitavista tuloksista voida yksilöidä yksittäisiä vastaajia. Tehtävän suorittamiseen menee noin 10-15 minuuttia.
Kun olet vastannut allaolevaan lomakkeeseen, testi aukeaa uudessa ikkunassa. Varmistathan, että selaimesi sallii uusien ikkunoiden avaamisen tästä ohjelmointimateriaalista!
Kun NetBeans alleviivaa yhden tai useamman rivin punaisella ja koodialueen oikeassa laidassa näkyy punaista, NetBeans kertoo että koodisi ei ole toimivassa tilassa, eikä ohjelmaasi voi tällöin myöskään suorittaa.
Ylläolevassa kuvassa NetBeans korostaa kahta virheellistä kohtaa. Ensimmäisessä kohdassa if-ehto on kirjoitettu väärin -- siitä puuttuu ainakin sulut -- ja toisessa kohdassa yritetään tulostaa muuttuja luk
, vaikka sellaista ei ole.
Kun editorissa olevien punaisten kohtien määrä kasvaa, etkä saa ohjelmaasi toimimaan kuten haluat, on hyvä pysähtyä ja palata taaksepäin pisteeseen, missä koodi toimi viimeksi. Voit palata taaksepäin valitsemalla undo tarpeeksi monta kertaa (ctrl + z).
Kun olet palannut taaksepäin, kerro ääneen mitä haluat tehdä. Mieti samalla mitkä ovat ne osat, joiden avulla pääset tavoitteeseesi. Etene pienin askelin ja toteuta ohjelmaasi osa kerrallaan. Ennen pitkää pienet osat tulevat sinulle tutuksi, ja opit yhä paremmin yhdistelemään niitä kokonaisiksi ohjelmiksi.
Tehtävien uudelleen alusta aloittamisessa ei ole mitään pahaa. Päinvastoin, kertaat tällöin ohjelman rakenteen toteuttamista, ja annat itsellesi aikaa oppia.
Eräs aloittelevan ohjelmoijan tyypillinen syy "punaisen koodin" lisääntymiselle on aaltosulkujen liikakäyttö, tai niiden liian vähäinen käyttö. Jokaiselle aaltosululle tulee löytyä ohjelmasta pari, sillä ne määrittelevät lohkoja, joissa ohjelmakoodia suoritetaan.
NetBeans auttaa tässä huomattavasti. Kun kirjoitat if
tai while
-ehdon, ja avaavan aaltosulkeen, koodi näyttää esimerkiksi seuraavalta:
Koodi ei käänny -- NetBeans vinkkaa, että virhe on viimeisellä rivillä. Syy on kuitenkin puuttuva aaltosulku.
Jos painat heti avaavan aaltosulkeen kirjoittamisen jälkeen enteriä, NetBeans luo kirjoittamallesi aaltosululle parin.
Punaista ei näy ja voit edetä :)
Jos ohjelmassasi on käytössä esim. muuttuja String sukunimi;
, ei koko muuttujan nimeä tarvitse kirjoittaa joka kerta kokonaan. Kokeile mitä tapahtuu kun kirjoitat s
ja sen jälkeen painat yhtäaikaa ctrl ja välilyönti. HUOM: joissakin käyttöjärjestelmissä automaattinen täydennys saadaan aikaan painamalla yhtä aikaa ctrl, alt ja välilyönti.
Kun painat tätä näppäinyhdistelmää, NetBeans ehdottaa muuttujia ja muuta.
Muuttujan sukunimi
voi valita NetBeansin tarjoamasta listasta. Vastaavalla tavalla NetBeans osaa täydentää muitakin nimiä, esim. komennon while
aikaansaamiseksi riittää kirjoittaa w ja painaa ctrl+välilyönti...
Muista että saat tehtyä tulostuskomennon System.out.println("") kirjoittamalla sout ja painamalla tabulaattoria eli q:n vasemmalla puolella olevaa näppäintä
Viikosta 2 eteenpäin materiaalissa on ohjelmointitehtävien lisäksi koodinluku- ja selitystehtäviä. Toisin kuin ohjelmointitehtävät, koodinluku- ja selitystehtävät eivät vaikuta kurssipisteisiin, eli kurssilla etenemisen kannalta niiden tekeminen on vapaaehtoista. Tehtävistä on kuitenkin hyötyä sekä kertaamisessa että kurssin aihepiiriin liittyvien "knoppien" ymmärtämisessä, joten niiden tekeminen on suositeltavaa.
Alla on kaksi esimerkkiä koodinlukutehtävästä. Kun avaat koodinlukutehtävän sitä klikkaamalla, huomaat että tehtävään liittyy sekä "Tarkista vastaus"-nappi että "Uusi tehtävä"-nappi. Uusi tehtävä -napin avulla voit hakea itsellesi uuden samaan teemaan liittyvän koodinlukutehtävän. Kokeile!
Selitystehtävät ovat taas tehtäviä, missä kirjoitat tehtävässä esitettyyn ongelmaan liittyvän vastauksen. Tehtävänanto kertoo mitä pitää tehdä. Selitysten ei tarvitse olla kovin pitkiä, mutta kuitenkin sellaisia, että kurssikaverisi ymmärtää mistä on kyse -- tulet myöhemmin kurssilla myös lukemaan ja pohtimaan muiden selityksiä. Voit testata allaolevaa selitystehtävää.
Edellämainittujen tehtävien lisäksi pajassa tehdään myös pariohjelmointia.
Pariohjelmoinnissa kaksi opiskelijaa työskentelee yhdellä tietokoneella. Toinen opiskelijoista on ohjelmoija, joka kontrolloi näppäimistöä ja hiirtä, ja toinen opiskelijoista on ohjaaja, joka tarkkailee etenemistä, kysyy kysymyksiä selventääkseen ymmärrystään ohjelmasta, tarjoaa ongelmiin ratkaisuehdotuksia, ja miettii ohjelman rakennetta kokonaisuutena. Rooleja vaihdetaan 5-10 minuutin välein.
Pariohjelmointi kehittää sekä konkreettista ohjelmointitaitoa, että pakottaa puhumaan ohjelmoinnista siihen liittyvillä käsitteillä. Pariohjelmointia käytetään myös työelämässä.
Kurssin ensimmäisen viikon oleellisimmat opittavat asiat liittyivät muuttujien ja toistolauseiden käyttöön. Jatketaan samalla teemalla.
Muuttujia käytetään tiedon säilyttämiseen sekä tiedon myöhempään noutamiseen. Muuttujan esittely tapahtui kertomalla ensin muuttujan tyyppi, esimerkiksi kokonaisluku (int
), jota seuraa muuttujan nimi, esimerkiksi luku
-- yhdessä int luku
. Muuttujan esittelyä seuraa tyypillisesti sijoitusoperaatio, minkä avulla muuttujalle asetetaan arvo, esimerkiksi int luku = 5
luo kokonaislukumuuttujan nimeltä luku ja asettaa siihen arvon 5.
Muuttujan arvoa voi käyttää myös uuden muuttujan esittelyssä ja arvon asetuksessa. Alla olevassa koodissa luodaan ensin muuttuja nimeltä pituus, jonka jälkeen luodaan muuttuja paino. Muuttujaan paino asetetaan puolet muuttujan pituus arvosta.
int pituus = 180; int paino = pituus / 2; System.out.println(paino);
90
Olemassaolevan muuttujan arvoa voidaan muuttaa. Tämä onnistuu sijoituslausekkeen avulla. Seuraavassa esitellään ensin muuttuja ika
, jolle asetetaan alkuarvoksi 1. Tämän jälkeen muuttujan ika
arvoa kasvatetaan yhdellä:
int ika = 1; System.out.println(ika); ika = ika + 1; // muuttujan ika uusi arvo on ika-muuttujan vanha arvo plus yksi System.out.println(ika);
Tulostuu:
1 2
Tarkastellaan rivin ika = ika + 1;
suoritusta vielä tarkemmin. Komento ika = ika + 1;
kasvattaa muuttujan ika
arvoa yhdellä. Käytännössä komennon suoritus tapahtuu siten, että ensin suoritetaan yhtäsuuruusmerkin oikealla puolella oleva lause ika + 1
. Tässä tietokone etsii ensin muuttujaa ika
. Koska muuttuja on esitelty aiemmin koodissa, se löytyy (sen arvo on 1
). Lauseen ika + 1
muuttujan ika
paikalle asetetaan arvo 1
. Lause on nyt muotoa 1 + 1
, jonka tietokone osaa laskea: tulokseksi tulee 2
. Komento on tämän jälkeen kokonaisuudessaan ika = 2
, mikä tarkoittaa "aseta muuttujan ika arvoksi 2".
Muuttujan arvon kasvattaminen yhdellä onnistuu myös seuraavasti:
int ika = 1; System.out.println(ika); ika++; // tarkoittaa samaa kuin ika = ika + 1; System.out.println(ika);
Komento ika++
muuntuu ohjelmaa suoritettaessa muotoon ika = ika + 1;
. Ohjelman tulostus on sama kuin edellisessä:
1 2
Toinen esimerkki:
int pituus = 100; System.out.println(pituus); pituus = pituus - 50; System.out.println(pituus); pituus = pituus * 2; System.out.println(pituus); pituus = pituus / 4; System.out.println(pituus); pituus--; // sama kuin pituus = pituus - 1; System.out.println(pituus);
Tulostuu:
100 50 100 25 24
Kuten edellisellä viikolla huomasimme, näppäimistöltä voidaan lukea käyttäjän antamaa syötettä Scanner
-apuvälineen avulla:
Scanner lukija = new Scanner(System.in); int pituus = 100; System.out.println(pituus); System.out.print("Paljonko poistetaan? "); pituus = pituus - Integer.parseInt(lukija.nextLine()); System.out.println(pituus); System.out.print("Paljonko lisätään? "); pituus = pituus + Integer.parseInt(lukija.nextLine()); System.out.println(pituus);
Tulostus esimerkiksi:
100 Paljonko poistetaan? 42 58 Paljonko lisätään? 1 59
Tarkastellaan rivin pituus = pituus - Integer.parseInt(lukija.nextLine());
suoritusta vielä tarkemmin.
Rivi on asetuslause, missä muuttujaan pituus
asetetaan lauseen pituus - Integer.parseInt(lukija.nextLine())
tuottama arvo. Lause pituus - Integer.parseInt(lukija.nextLine())
suoritetaan seuraavasti:
pituus
arvon. Koska muuttuja on luotu aiemmin, se löytyy: sen arvo on 100
. Nyt lasku on muotoa 100 - Integer.parseInt(lukija.nextLine());
.Integer.parseInt(lukija.nextLine())
:
lukija.nextLine()
. Tämä johtaa siihen, että ohjelma jää odottamaan käyttäjältä syötettä. Kun käyttäjä antaa syötteen, esimerkiksi "42", vaihtuu komennon lukija.nextLine()
paikalle käyttäjän syöttämä merkkijono. Seuraavaksi suoritettava komento on nyt Integer.parseInt("42");
.Integer.parseInt("42")
muuttaa tekstimuuttujan, jonka arvo on "42"
, kokonaislukumuuttujaksi, jonka arvo on 42
.Integer.parseInt(lukija.nextLine())
paikalle asetetaan sen suorituksesta saatu arvo, tässä 42
. Nyt lasku on muotoa 100 - 42
.100 - 42
, jonka tulos on 58
.Lopulta lause on muotoa pituus = 58
, eli muuttujan pituus
arvoksi asetetaan 58
.
Tee ohjelma, joka kysyy käyttäjältä kolme lukua ja tulostaa niitten summan. Huom! Käytä tehtäväpohjaan valmiiksi luotuja muuttujia -- älä siis luo uusia muuttujia koodiin. Tee ohjelmastasi seuraavan muotoinen:
Scanner lukija = new Scanner(System.in); int summa = 0; int luettu; // KIRJOITA OHJELMA TÄHÄN // ÄLÄ KÄYTÄ MUITA MUUTTUJIA KUIN lukija, summa JA luettu! System.out.println("Summa: " + summa);
Anna ensimmäinen luku: 3 Anna toinen luku: 6 Anna kolmas luku: 12 Summa: 21
Kertaa ennen tehtävän aloitusta viime viikon kappale Toiston alkeet.
Tee ohjelma, joka lukee käyttäjältä lukuja ja tulostaa niiden summan. Ohjelma lopettaa kyselemisen kun syötetään luku 0. Käytä seuraavaa pohjaa, jonka saat myös palautusautomaatilta:
Scanner lukija = new Scanner(System.in); int summa = 0; System.out.print("Anna lukuja, nolla lopettaa: "); while (true) { int luettu = Integer.parseInt(lukija.nextLine()); if (luettu == 0) { break; } // TEE JOTAIN TÄÄLLÄ System.out.println("Summa nyt: " + summa); } System.out.println("Summa lopussa: " + summa);
Ohjelman tulee toimia seuraavasti:
Anna lukuja, nolla lopettaa: 3 Summa nyt: 3 2 Summa nyt: 5 1 Summa nyt: 6 1 Summa nyt: 7 0 Summa lopussa: 7
Koska olemassaolevan muuttujan arvon muuttaminen on hyvin yleinen operaatio, on sitä varten olemassa erityiset sijoitusoperaatiot.
int pituus = 100; pituus += 10; // sama kuin pituus = pituus + 10; pituus -= 50; // sama kuin pituus = pituus - 50;
Olemassaolevan muuttujan arvoa muuttava sijoitusoperaatio merkitään muuttuja muutostyyppi= muutos
, esimerkiksi muuttuja += 5
. Huomaa, että muuttujan tulee olla olemassa ennen kuin sille voidaan asettaa arvo. Muuttuja tulee siis aina esitellä ennen kuin se on käytettävissä. Muuttujan esittely tapahtuu kertomalla muuttujan tyyppi ja nimi.
Seuraava esimerkki ei toimi, sillä muuttujaa leveys
ei ole esitelty.
leveys += 100; // ei toimi!
Kun muuttuja on esitelty, laskukin toimii oikein.
int leveys = 100; // muuttujan esittely; "on olemassa int-tyyppinen muuttuja nimeltä leveys, jonka arvo on 100" leveys += 100; // toimii!
Myös muille kuin yhteen- ja vähennyslaskuille on Javassa vastaavat sijoitusoperaatiot.
int pituus = 100; System.out.println(pituus); pituus *= 10; // sama kuin pituus = pituus * 10; System.out.println(pituus); pituus /= 100; // sama kuin pituus = pituus / 100; System.out.println(pituus); pituus %= 3; // sama kuin pituus = pituus % 3; System.out.println(pituus);
100 1000 10 1
Kun muuttuja esitellään, se ei ole kaikkialla olemassa. Muuttujan olemassaoloon liittyy oleellisesti kaksi sääntöä:
if (luku > 10) { // ei toimi sillä muuttujaa luku ei vielä tunneta! System.out.println("Jee!"); } int luku = 12;
int luku = 12; if (luku > 10) { // toimii! System.out.println("Jee!"); }
int luku = 12; if (luku > 10) { System.out.println("Jee!"); int tulostus = 52; } System.out.println(tulostus); // ei toimi sillä muuttuja tulostus on olemassa vain if-lauseen lohkojen sisällä.
int luku = 12; int tulostus = 0; if (luku > 10) { System.out.println("Jee!"); tulostus = 52; } System.out.println(tulostus); // toimii!
Toisen säännön yhteydessä myös ensimmäinen sääntö pätee. Muuttuja on olemassa vain sen esittelyhetkestä eteenpäin, ei koskaan ennen esittelyhetkeä.
Opimme edellisellä viikolla (kts. Toiston alkeet) toteuttamaan while (true)
-komennon avulla ohjelman, joka toistaa tiettyä komentosarjaa komennon break
suorittamiseen asti. Kerrataanpa tätä hieman:
Komento break
ei ole ainoa tapa lopettaa toistoa. Toistokomennon yleinen muoto on while (ehto)
, jossa ehtona voi olla mikä tahansa totuusarvoinen lauseke, eli ehto voi olla täsmälleen samaa muotoa kuin if
-komentojen ehdot.
Seuraavassa esimerkissä tulostetaan luvut 1, 2, ..., 5. Kun luku
-muuttujan arvo on yli 5, while
-ehto ei ole enää voimassa ja toistaminen lopetetaan.
int luku = 1; while (luku < 6) { System.out.println(luku); luku++; // luku++ tarkoittaa samaa kuin luku = luku + 1 }
Lue ylläoleva "niin pitkään kuin muuttujan luku arvo on pienempi kuin 6, tulosta muuttujan luku arvo ja kasvata muuttujan luku arvoa yhdellä".
Ylläolevassa koodissa ehdossa olevaa muuttujaa luku
kasvatettiin jokaisella kierroksella yhdellä. Päivitys voi olla mikä tahansa, eli ehdossa olevan muuttujan ei tarvitse suinkaan aina kasvaa yhdellä, esim:
int luku = 1024; while (luku >= 1) { System.out.println(luku); luku /= 2; // luku /= 2 tarkoittaa samaa kuin luku = luku / 2 }
Screencast aiheesta:
Tee seuraavat tehtävät while-komennon avulla:
Tee ohjelma, joka tulostaa kokonaisluvut väliltä 1–100.
Ohjelman tulostus on seuraava:
1 2 3 (välissä paljon rivejä) 98 99 100
Tee ohjelma, joka tulostaa kokonaisluvut väliltä 100–1.
Ohjelman tulostus on seuraava:
100 99 98 (välissä paljon rivejä) 3 2 1
Vihje: aseta toistossa käytettävän apumuuttujan arvoksi aluksi 100 ja vähennä muuttujan arvoa yhdellä toiston sisällä.
Tee ohjelma, joka tulostaa parilliset kokonaisluvut väliltä 2–100.
2 4 6 (välissä paljon rivejä) 96 98 100
Kirjoita ohjelma, joka tulostaa kokonaisluvut 1:stä käyttäjän antamaan lukuun asti.
Mihin asti? 3 1 2 3
Mihin asti? 5 1 2 3 4 5
Vihje: käyttäjältä lukemasi luku toimii nyt whilen lopetusehdon ylärajana. Muista että Javassa a <= b
tarkoittaa a pienempi tai yhtä suuri kuin b.
Lisää ohjelmaan käyttäjältä kysyttävä alaraja.
Mihin asti? 8 Mistä lähtien? 5 5 6 7 8
Jos tavoite on suurempi kuin lähtökohta ei tulostu mitään:
Mihin asti? 12 Mistä lähtien? 16
Huom! muista että ala- ja yläraja voivat olla myös negatiivisia!
Robotti on taas täällä! Käytössä olevat komennot ovat Ohjain.kaynnista()
, Ohjain.sammuta()
, Ohjain.vasen()
, Ohjain.oikea()
ja Ohjain.liiku()
.
Kirjoita ohjelma, joka kysyy käyttäjältä piirrettävien portaiden lukumäärää.
Kun käyttäjä syöttää esimerkiksi luvun kolme, tulee robotin piirtää kolme porrasaskelmaa.
Montako ylös? 3
Täydennä ohjelmaa siten, että robotti kulkee portaita myös alas.
Alla olevassa esimerkissä robotti nousee ensin viisi askelta ylös ja laskeutuu sitten kolme askelta alas.
Montako ylös? 5 Montako alas? 3
Tarkastellaan seuraavaa toistolausetta.
int luku = 1; while (luku != 2) { System.out.println(luku); luku = 2; System.out.println(luku); luku = 1; }
Ohjelman tulostus seuraavanlainen:
1 2 1 2 1 2 ...
Vaikka muuttujan luku
arvo on välillä 2, toistolauseen suoritus ei lopu koskaan.
Toistolauseen ehto tarkistetaan vain kun toistolauseen toistaminen aloitetaan sekä silloin kun koodin suoritus on päässyt toistolauseen lopettavaan aaltosulkuun asti. Jos ehto on totta, suoritus hyppää takaisin toistolauseen alkuun, ja jos ehto on epätotta, suoritus jatkuu toistolausetta seuraavalta riviltä.
Vaikka muuttujan luku
arvo on ylläolevassa toistolauseessa välillä 2, ei se ole koskaan 2 toistolauseen lopussa. Lopussa ehto luku != 2
on aina totta, ja suoritus hyppää takaisin koodin alkuun.
Usein ohjelmissa esiintyy toisto, jonka jokaisella toistokerralla muutetaan yhden tai useamman muuttujan arvoa. Seuraava ohjelma laskee tulon 4*3 hieman kömpelöllä tavalla eli summana 3 + 3 + 3 + 3:
int tulos = 0; int i = 0; while (i < 4) { tulos += 3; // tarkoittaa samaa kuin tulos = tulos + 3; i++; // tarkoittaa samaa kuin i = i + 1; } System.out.println(tulos);
Alussa tulos = 0
. Toiston jokaisella kierroksella muuttujan tulos
arvoon lisätään luku 3
. Koska toistoja on 4, on lopulta muuttujan arvona 3 * 4
eli 12, jonka ohjelma lopulta tulostaa.
Yksi näppärä tapa muuttujien arvojen tarkasteluun toistolauseessa on taulukko. Seuraavaan taulukkoon on kirjoitettu auki edellä olevassa ohjelmassa olevien muuttujien tulos
ja i
arvot kullakin toistolauseen ehdon i < 4
vertailuhetkellä.
tulos | i | i < 4 |
---|---|---|
0 | 0 | true |
3 | 1 | true |
6 | 2 | true |
9 | 3 | true |
12 | 4 | false |
Toistolauseen suoritus loppuu kun muuttujan summa
arvo on 12 ja muuttujan i
arvo on 4 (ehto i < 4
on tällöin epätotta).
Tee ohjelma, joka laskee summan 1+2+3+...+n, missä n on käyttäjän syöttämä luku.
Esimerkkitulostuksia:
Mihin asti? 3 Summa on 6
Edellisessä esimerkissä laskettiin 1 + 2 + 3 = 6
Mihin asti? 7 Summa on 28
Ja nyt laskettiin 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28
Vihje: Tee ohjelma while
-komennon avulla. Käytä ohjelmassasi apumuuttujaa toistokertojen muistamiseen. Lisää jokaisella toistokerralla toistokerrat muistavan muuttujan arvo apumuuttujaan johon lasket summan arvon.
Muuta edellistä tehtävää siten, että käyttäjä määrää summan laskemisen aloituskohdan. Voit olettaa, että käyttäjä antaa ensin pienemmän luvun ja sitten suuremman luvun.
Esimerkkitulostuksia:
Ensimmäinen: 3 Viimeinen: 5 Summa on 12
Edellisessä laskettiin 3 + 4 + 5 = 12
Ensimmäinen: 2 Viimeinen: 8 Summa on 35
Ja nyt laskettiin 2 + 3 + 4 + 5 + 6 + 7 + 8 = 35
Tee ohjelma, joka laskee luvun n kertoman.
Kertoma n!
lasketaan kaavalla 1*2*3*...*n. Esimerkiksi luvun 4 kertoma on 24, eli 4! = 1*2*3*4 = 24. Lisäksi on määritelty, että luvun 0 kertoma on 1, eli 0! = 1.
Esimerkkitulostuksia:
Anna luku: 3 Kertoma on 6
Nyt laskettiin 1 * 2 * 3 = 6
Anna luku: 10 Kertoma on 3628800
Ja nyt laskettiin 1 * 2 * 3 * ... * 8 * 9 * 10 = 3628800
Lisätietoa: Kertomaa käytetään erityisesti todennäköisyyslaskennassa tilanteissa, missä halutaan esimerkiksi tarkastella jonkin joukon kaikkia erilaisia järjestyksiä. Esimerkiksi viiden hengen ryhmän voi järjestää 5! erilaiseen jonoon, ja 52 kortin korttipakka voi olla 52! erilaisessa järjestyksessä. Kertomaa voi käyttää myös kombinaatioiden laskemiseen; esimerkiksi 52 kortin korttipakasta voi ottaa viisi korttia 52! / (5! * (52 - 5)!) erilaisessa järjestyksessä.
Tee ohjelma, joka laskee summan 20+21+22+...+2n, missä n on käyttäjän syöttämä luku. Merkintä 2i tarkoittaa luvun 2 korottamista potenssiin i, esimerkiksi 24 = 2*2*2*2 = 16. Javassa merkintä ab ei ole käytössä, mutta potenssin voi laskea komennolla Math.pow(luku, potenssi)
. Huom. komento palauttaa double
-tyyppisen eli liukulukutyyppisen luvun. Liukulukutyyppisen luvun voi muuttaa kokonaisluvuksi (int
-tyyppiseksi) seuraavasti: int tulos = (int) Math.pow(2, 3)
. Lasku asettaa muuttujaan tulos laskun 2 potenssiin 3 arvon.
Esimerkkitulostuksia:
Anna luku: 3 Tulos on 15
Anna luku: 7 Tulos on 255
Yksi suosituimmista toistolauseisiin liittyvistä ohjelmointivirheistä on vahingossa tehty ikuinen silmukka. Seuraavassa yritetään tulostaa ruudulle 3 kertaa "En enää ikinä ohjelmoi ikuista silmukkaa":
int i = 0; while (i < 3) { System.out.println("En enää ikinä ohjelmoi ikuista silmukkaa"); }
Toistokertojen määrää kontrolloiva muuttuja i
on aluksi 0 ja toistoja on tarkoitus tehdä niin kauan kuin ehto i < 3
on totta. Käy kuitenkin hieman hassusti: muuttujan i
arvoa ei muuteta toistolauseessa, joten toistoehto pysyy ikuisesti totena.
i | i < 3 |
---|---|
0 | true |
0 | true |
0 | true |
0 | true |
0 | true |
... |
Seuraavassa tehtävässä tehdään oikeastaan ainoastaan yksi ohjelma, mutta ohjelman rakentaminen tapahtuu hyvin pienissä paloissa. Tämä on ehdottoman suositeltava tapa AINA kun ohjelmoit.
Eli kun teet ohjelmaa, oli se sitten harjoitustehtävä tai oma projektisi, kannattaa edetä hyvin pienissä paloissa. Älä koskaan yritä ratkaista koko ongelmaa kerralla. Aloita jollain helpolla asialla jonka tiedät varmasti osaavasi. Esim. seuravaavassa tehtäväsarjassa keskitytään aluksi pelkästään siihen, että osataan pysäyttää ohjelma käyttäjän syöttäessä luvun -1. Kun yksi ohjelman osa on saatu toimimaan, voidaan siirtyä ratkaisemaan jotain seuraavaa varsinaisen ongelman osaongelmaa.
Osa kurssin tehtäviä on valmiiksi osiin pilkottuja. Usein osat pitää vielä pilkkoa ohjelmoinnin kannalta vieläkin pienempiin paloihin. Kannattaa tehdä siten, että suoritat ohjelman lähes jokaisen uuden koodirivin jälkeen. Tällöin varmistat, että ratkaisu on etenemässä haluttuun suuntaan.
Tämä tehtäväsarja muodostaa yhden isomman ohjelman, jonka toiminnallisuus toteutetaan pienissä paloissa. Jos et tee tehtäväsarjaa loppuun asti, voit lähettää sen tarkastettavaksi vajaatekoisenakin. Tämä onnistuu painamalla testausnapin oikealla puolella olevasta "submit"-napista eli pienestä ylöspäinosoittavasta nuolesta. Vaikka palautusautomaatti valittaakin vielä tekemättä olevien tehtävänosien testeistä, kirjautuvat jo tekemiesi osien pisteet.
Huom: nyt (ja jatkossa) jokainen isomman tehtävän "alitehtävä" on saman arvoinen tehtävä kuin alikohdaton tehtävä. Tehtävä 41 siis vastaa viittä normaalia tehtävää.
Tee ohjelma, joka kysyy käyttäjältä lukuja (ohjelma tulostaa käyttäjälle aluksi "Syötä luvut:"), kunnes käyttäjä antaa luvun -1. Kun käyttäjä syöttää luvun -1, ohjelma tulostaa "Kiitos ja näkemiin!" ja päättyy.
Syötä luvut: 5 2 4 -1 Kiitos ja näkemiin!
Laajenna edellistä ohjelmaa siten, että ohjelma ilmoittaa käyttäjän syöttämien lukujen summan. (Lukua -1 ei lasketa mukaan.)
Syötä luvut: 5 2 4 -1 Kiitos ja näkemiin! Summa: 11
Laajenna edellistä ohjelmaa siten, että ohjelma ilmoittaa myös käyttäjien antamien lukujen lukumäärän. (Lukua -1 ei lasketa mukaan.)
Syötä luvut: 5 2 4 -1 Kiitos ja näkemiin! Summa: 11 Lukuja: 3
Muuta edellistä ohjelmaa siten, ohjelma ilmoittaa lukujen keskiarvon. (Lukua -1 ei lasketa mukaan.)
Syötä luvut: 5 2 4 -1 Kiitos ja näkemiin! Summa: 11 Lukuja: 3 Keskiarvo: 3.666666666666
Laajenna edellistä ohjelmaa siten, että ohjelma ilmoittaa parillisten ja parittomien lukujen määrän. (Lukua -1 ei lasketa mukaan.)
Syötä luvut: 5 2 4 -1 Kiitos ja näkemiin! Summa: 11 Lukuja: 3 Keskiarvo: 3.666666666666 Parillisia: 2 Parittomia: 1
Olemme tehneet peräkkäin jo muutamia toistotehtäviä, joissa toistoehto on muotoa:
int i = 1; while (i < 10) { // ... i++; }
Ylläolevassa rungossa muuttujaa i
käytetään toistokertojen määrän muistamiseen, ja lopetusehto perustuu vertailuun i < 10
.
Muistellaan taas toiston lopetusta. Toiston lopetuksen ei tarvitse perustua toistokertojen laskemiseen. Katsotaan esimerkkiä jossa kysytään käyttäjän ikää. Jos ikä ei ole välillä 1-120, annetaan huomautus ja kysytään ikä uudelleen. Toistolauseen while-lauseen ehto voi siis olla mitä tahansa totuusarvon tuottavaa.
System.out.println("ikäsi: "); int ika = Integer.parseInt(lukija.nextLine()); while (ika < 1 || ika > 120) { // ikä pienempi kuin 1 TAI suurempi kuin 120 System.out.println("Valehtelet"); if (ika < 1) { System.out.println("Olet niin nuori ettet osaa kirjoittaa"); } else if (ika > 120) { System.out.println("Olet niin vanha ettet osaa käyttää tietokonetta"); } System.out.println("syötä ikäsi uudelleen: "); ika = Integer.parseInt(lukija.nextLine(); } System.out.println("Ikäsi on siis "+ ika);
Ohjelman olisi voinut tehdä myös vanhaa tuttua while (true)
-rakennetta käyttäen:
System.out.println("ikäsi: "); int ika = Integer.parseInt(lukija.nextLine()); while (true) { if (ika >= 1 && ika <= 120) { // ikä 1:n JA 120:n välillä break; // lopetetaan toisto } System.out.println("Valehtelet"); if (ika < 1) { System.out.println("Olet niin nuori ettet osaa kirjoittaa"); } else { // ikä siis yli 120 System.out.println("Olet niin vanha ettet osaa käyttää tietokonetta"); } System.out.println("syötä ikäsi uudelleen: "); ika = Integer.parseInt(lukija.nextLine()); } System.out.println("Ikäsi on siis "+ ika);
Edellä esitellyn while
-toistolauseen lisäksi Javassa toiston voi hoitaa myös for-toistolauseen avulla. Varsinaisesti rupeamme käyttämään for-toistolausetta vasta hieman myöhemmin kurssilla, mutta jo tässä vaiheessa mainittakoon, että while-toistolauseen voi toteuttaa myös toisella tavalla.
int i = 0; while (i < 5) { System.out.println(i); i++; }
Edellinen while-toistolause tehtäisiin for-toistolauseen avulla seuraavasti:
for (int i = 0; i < 5 ; i++) { System.out.println(i); }
For-toistolause sisältää samalla rivillä indeksimuuttujan alustuksen (int i = 0;
), toistoehton (i < 10;
) ja indeksimuuttujan (i++
) kasvatuksen puolipistein eroteltuna.
Olemme käyttäneet useita erilaisia komentoja Javassa: sijoitusta, laskutoimituksia, vertailuja, if:iä ja whileä. Ruudulle tulostaminen on tehty "komentoa" System.out.println()
käyttäen. Tuttuja ovat myös lukija.nextLine()
ja sen kanssa usein nähty Integer.parseInt()
.
Huomaamme, että jälkimmäinen joukko edellä lueteltuja komentoja poikkeaa if
:istä ja while
:stä ym. siinä, että komennon perässä on sulut ja joskus sulkujen sisällä komennolle annettava syöte. "Sulkuihin päättyvät" eivät oikeastaan olekaan komentoja vaan metodeja.
Teknisesti ottaen metodi tarkoittaa koodinpätkää, jota voi kutsua muualta ohjelmakoodista. Koodirivi System.out.println("olen metodille annettava parametri!")
siis tarkoittaa, että kutsutaan metodia, joka suorittaa ruudulle tulostamisen. Metodin suorituksen jälkeen palataan takaisin koodiin siihen kohtaan missä ennen metodikutsua oltiin menossa. Metodille suluissa annettua syötettä kutsutaan metodin parametriksi.
Parametrin lisäksi metodilla voi olla paluuarvo. Esim. tuttu koodinpätkä:
int luku = Integer.parseInt(lukija.nextLine());
sisältää kaksi metodikutsua. Ensin kutsutaan sisempänä olevaa metodia lukija.nextLine
. Metodilla on paluuarvonaan käyttäjän syöttämä merkkijono. Seuraavaksi kutsutaan metodia Integer.parseInt
. Metodikutsun parametrina on merkkijono jonka metodin lukija.nextLine
kutsu palautti ja metodin paluuarvona on merkkijonoa vastaava kokonaisluku.
Metodin nimeen näyttää liittyvän piste, esim. lukija.nextLine()
. Oikeastaan tässä metodin nimi onkin pisteen oikeanpuoleinen osa, eli nextLine()
. Pisteen vasemmanpuoleinen osa, eli tässä lukija
kertoo kenen metodista on kyse. Eli kyseessä on lukijan metodi nextLine. Opimme hiukan myöhemmin tarkemmin mistä tässä pisteen vasemmanpuoleisessa osassa on kyse. Tarkka lukija tietysti huomaa, että System.out.println()
:ssa on "kaksi pistettä". Metodin nimi tässä on println, ja System.out
on se kenen metodista on kyse. Karkeasti ottaen System.out
tarkoittaa koneen näyttöä.
Tähän mennessä käyttämämme metodit ovat kaikki olleet Javan valmiita metodeita. Nyt opettelemme tekemään omia metodeita.
Olemme tähän mennessä ohjelmoineet ohjelmamme siten, että kaikki tapahtuu yhdessä jatkumossa ja koodia luetaan ylhäältä alas.
Edellä mainittiin että "metodi tarkoittaa koodinpätkää, jota voi kutsua muualta ohjelmakoodista". Javan valmiita metodeja on käytetty jo oikeastaan ensimmäisestä ohjelmasta lähtien.
Javan valmiiden metodien käytön lisäksi ohjelmoija voi kirjoittaa itse metodeja joita sovellus kutsuu. Oikeastaan on hyvin poikkeuksellista jos ohjelmassa ei ole yhtään itse kirjoitettua metodia. Tästä lähtien lähes jokainen kurssilla tehty ohjelma sisältääkin itsekirjoitettuja metodeja.
Ohjelmarunkoon metodit kirjoitetaan main:in aaltosulkeiden ulkopuolelle mutta kuitenkin "uloimmaisten" aaltosulkeiden sisäpuolelle, joko mainin ylä- tai alapuolelle
import java.util.Scanner; public class Esimerkki { public static void main(String[] args) { Scanner lukija = new Scanner(System.in); // ohjelmakoodi } // omia metodeja tänne }
Luodaan metodi tervehdi
.
public static void tervehdi() { System.out.println("Terveiset metodimaailmasta!"); }
Ja asetetaan se metodeille kuuluvalle paikalle.
import java.util.Scanner; public class Esimerkki { public static void main(String[] args) { Scanner lukija = new Scanner(System.in); // ohjelmakoodi } // omia metodeja tänne public static void tervehdi() { System.out.println("Terveiset metodimaailmasta!"); } }
Metodin määrittely sisältää kaksi osaa. Metodimäärittelyn ensimmäisellä rivillä on metodin nimi eli tervehdi. Nimen vasemmalla puolella tässä vaiheessa määreet public static void
. Metodin nimen sisältävän rivin alla on aaltosulkeilla erotettu koodilohko, jonka sisälle kirjoitetaan metodin koodi, eli ne komennot jotka metodia kutsuttaessa suoritetaan. Metodimme tervehdi
ei tee muuta kuin kirjoittaa rivillisen tekstiä ruudulle.
Itsekirjoitetun metodin kutsu on helppoa, kirjoitetaan metodin nimi ja perään sulut ja puolipiste. Seuraavassa main eli pääohjelma kutsuu tervehdi-metodia yhteensä neljä kertaa.
import java.util.Scanner; public class OhjelmaRunko { public static void main(String[] args) { Scanner lukija = new Scanner(System.in); // ohjelmakoodi System.out.println("Kokeillaan pääsemmekö metodimaailmaan:"); tervehdi(); System.out.println("Näyttää siltä, kokeillaan vielä:"); tervehdi(); tervehdi(); tervehdi(); } // omat metodit public static void tervehdi() { System.out.println("Terveiset metodimaailmasta!"); } }
Ohjelman suoritus saa aikaan seuraavan tulosteen:
Kokeillaan pääsemmekö metodimaailmaan: Terveiset metodimaailmasta! Näyttää siltä, kokeillaan vielä: Terveiset metodimaailmasta! Terveiset metodimaailmasta! Terveiset metodimaailmasta!
Huomionarvoista tässä on koodin suoritusjärjestys. Koodin suoritus etenee siten, että pääohjelman -- eli main:in -- rivit suoritetaan ylhäältä alas yksi kerrallaan. Koodirivin ollessa metodikutsu, mennään suorittamaan metodissa olevat koodirivit, jonka jälkeen palataan kohtaan, josta metodin kutsu tapahtui. Tarkemmin ottaen metodikutsun jälkeiselle riville.
Jos ollaan tarkkoja niin pääohjelma eli main on itsekin metodi. Kun ohjelma käynnistyy, kutsuu käyttöjärjestelmä main:ia. Metodi main on siis ohjelman käynnistyspiste, jonka ylimmältä riviltä ohjelman suoritus lähtee liikkeelle. Ohjelman suoritus loppuu kun päädytään mainin loppuun.
Jatkossa kun esittelemme metodeja, emme erikseen mainitse että niiden täytyy sijaita omalla paikallaan. Metodia ei esimerkiksi voi määritellä toisen metodin sisällä.
Tee metodi tulostaTeksti
, joka tulostaa tekstin "Alussa olivat suo, kuokka ja Java." sekä rivinvaihdon.
public static void main(String[] args) { tulostaTeksti(); } public static void tulostaTeksti() { // kirjoita koodia tähän }
Ohjelman tulostus:
Alussa olivat suo, kuokka ja Java.
Laajenna edellistä ohjelmaa siten, että pääohjelma kysyy käyttäjältä, montako kertaa teksti tulostetaan eli montako kertaa metodia kutsutaan.
public static void main(String[] args) { // kysy käyttäjältä, montako kertaa teksti tulostetaan // kutsu metodia tulostaTeksti while-komennon avulla useita kertoja } public static void tulostaTeksti() { // kirjoita koodia tähän }
Ohjelman tulostus:
Kuinka monta? 7 Alussa olivat suo, kuokka ja Java. Alussa olivat suo, kuokka ja Java. Alussa olivat suo, kuokka ja Java. Alussa olivat suo, kuokka ja Java. Alussa olivat suo, kuokka ja Java. Alussa olivat suo, kuokka ja Java. Alussa olivat suo, kuokka ja Java.
Huom: tulosta kehote Kuinka monta? omalle rivilleen!
Metodit nimetään siten, että ensimmäinen sana kirjoitetaan pienellä ja loput alkavat isolla alkukirjaimella, tälläisestä kirjoitustavasta käytetään nimitystä camelCase. Tämän lisäksi, metodin sisällä koodi on sisennetty taas neljä merkkiä.
Väärin | Oikein |
---|---|
public static void Tama_metodi_sanoo_mur ( ) { System.out.println("mur"); } |
public static void tamaMetodiSanooMur() { System.out.println("mur"); } |
Metodista saa huomattavasti monikäyttöisemmän antamalla sille parametreja. Parametrit ovat muuttujia, jotka määritellään metodin ylimmällä rivillä metodin nimen jälkeen olevien sulkujen sisällä. Kun metodia kutsutaan, sen parametreille annetaan arvot kutsuvaiheessa.
Seuraavassa esimerkissä määritellään parametrillinen metodi tervehdi
, jolla on String-tyyppinen parametri nimi
.
public static void tervehdi(String nimi) { System.out.println("Hei " + nimi + ", terveiset metodimaailmasta!"); }
Kutsutaan metodia tervehdi
siten, että parametrin nimi
arvoksi asetetaan ensimmäisellä kutsulla Verna
ja toisella kutsulla Chang
.
public static void main(String[] args) { tervehdi("Verna"); tervehdi("Chang"); }
Hei Verna, terveiset metodimaailmasta! Hei Chang, terveiset metodimaailmasta!
Aivan kuten Javan valmista System.out.println()
-metodia kutsuttaessa, voi oman metodin kutsussa parametrina käyttää monimutkaisempaa ilmausta:
public static void main(String[] args) { String nimi1 = "Ilari"; String nimi2 = "S"; tervehdi(nimi1 + " " + nimi2); int ika = 20; tervehdi("Veera " + ika + " vuotta"); }
Hei Ilari S, terveiset metodimaailmasta! Hei Veera 20 vuotta, terveiset metodimaailmasta!
Molemmissa tapauksissa metodilla on edelleen vain 1 parametri. Jos parametri on lause, kuten esimerkiksi nimi1 + " " + nimi2
, lasketaan lauseen arvo ennen metodin kutsumista. Ensimmäisessä tapauksessa parametrin arvo saadaan merkkijonokatenaationa nimi1 + " " + nimi2
, joka on arvoltaan Ilari S, ja jälkimmäisessä tapauksessa merkkijonokatenaatiosta "Veera " + ika + " vuotta"
, joka on arvoltaan Veera 20 vuotta.
Metodille voidaan määritellä useita parametreja. Tällöin metodin kutsussa parametrit annetaan samassa järjestyksessä.
public static void tervehdi(String nimi, String mistaTerveiset) { System.out.println("Hei " + nimi + ", terveiset " + mistaTerveiset); }
String kuka = "Milla"; String terveiset = "Monacosta"; tervehdi(kuka, terveiset); tervehdi(kuka, terveiset + " ja Kumpulasta");
Jälkimmäisessä tervehdi
-funktion kutsussa toinen parametri muodostetaan katenoimalla muuttujaan terveiset
teksti " ja Kumpulasta"
. Tämä suoritetaan ennen varsinaista funktion suoritusta.
Hei Milla, terveiset Monacosta Hei Milla, terveiset Monacosta ja Kumpulasta
main ei ole suinkaan ainoa joka voi kutsua metodeita. Metodit voivat kutsua myös toisiaan. Tehdään metodi tervehdiMontaKertaa
, joka tervehtii käyttäjää useasti metodin tervehdi
avulla:
public static void tervehdi(String nimi) { System.out.println("Hei " + nimi + ", terveiset metodimaailmasta!"); } public static void tervehdiMontaKertaa(String nimi, int kerrat) { int i = 0; while (i < kerrat) { tervehdi(nimi); i++; } } public static void main(String[] args) { tervehdiMontaKertaa("Ada-Maaria", 3); System.out.println("ja"); tervehdiMontaKertaa("Juha", 2); }
Tulostuu:
Hei Ada-Maaria, terveiset metodimaailmasta! Hei Ada-Maaria, terveiset metodimaailmasta! Hei Ada-Maaria, terveiset metodimaailmasta! ja Hei Juha, terveiset metodimaailmasta! Hei Juha, terveiset metodimaailmasta!
Screencast aiheesta:
Tee metodi tulostaTahtia
,
joka tulostaa annetun määrän tähtiä ja rivinvaihdon.
Tee metodi seuraavaan runkoon:
public static void tulostaTahtia(int maara) { // yhden tähden saat tulostettua komennolla // System.out.print("*"); // kutsu tulostuskomentoa n kertaa // tulosta lopuksi rivinvaihto komennolla // System.out.println(""); } public static void main(String[] args) { tulostaTahtia(5); tulostaTahtia(3); tulostaTahtia(9); }
Ohjelman tulostus:
***** *** *********
huom: moniosaisen tehtävät voi palauttaa palvelimelle (painamalla testausnapin oikealla puolella olevaa nappia) vaikka kaikki osat eivät olisikaan tehty. Palvelin valittelee tällöin tekemättömien osien testeistä, tehdyt osat palvelin kirjaa.
Tee metodi tulostaNelio(int sivunpituus)
joka tulostaa neliön käyttäen tulostaTahtia
-metodia. Siis esimerkiksi kutsu tulostaNelio(4)
tulostaa seuraavaa:
**** **** **** ****
Huom: tehtävässä ei riitä että tulostus näyttää oikealta, tulostaNelio-metodin sisällä neliön "rivien" tulostus tulee tehdä tulostaTahtia-metodia käyttäen.
Ohjelmaa tehdessäsi kannattaa varmistaa main:iin kirjoitetun testikoodin avulla että metodit toimivat vaaditulla tavalla.
Tee metodi tulostaSuorakulmio(int leveys, int korkeus)
joka tulostaa suorakulmion käyttäen tulostaTahtia
-metodia. Siis esimerkiksi kutsu tulostaSuorakulmio(17,3)
tulostaa seuraavaa:
***************** ***************** *****************
Tee metodi tulostaKolmio(int koko)
joka tulostaa kolmion käyttäen tulostaTahtia
-metodia. Siis esimerkiksi kutsu tulostaKolmio(4)
tulostaa seuraavaa:
* ** *** ****
Tee metodi tulostaTyhjaa(int maara)
joka tulostaa maara
kappaletta välilyöntejä. Metodi ei tulosta rivinvaihtoa.
Joudut myös joko kopioimaan edellisen tehtävän vastauksestasi metodin tulostaTahtia
tai toteuttamaan sen uudelleen tämän tehtävän tehtäväpohjaan.
Tee metodi tulostaKolmio(int koko)
joka tulostaa kolmion käyttäen tulostaTyhjaa
- ja tulostaTahtia
-metodeja. Siis esimerkiksi kutsu tulostaKolmio(4)
tulostaa seuraavaa:
* ** *** ****
Tee metodi jouluKuusi(int korkeus)
joka tulostaa joulukuusen. Joulukuusi koostuu annetun korkuisesta kolmiosta ja jalasta. Jalka on kaksi tähteä korkea ja kolme tähteä leveä ja se on keskellä kolmion pohjaa.
Kuusi tulee rakentaa käyttämällä tulostukseen metodeja tulostaTyhjaa
ja tulostaTahtia
Esimerkiksi kutsu jouluKuusi(4)
tulostaa seuraavaa:
* *** ***** ******* *** ***
Kutsu jouluKuusi(10)
tulostaa:
* *** ***** ******* ********* *********** ************* *************** ***************** ******************* *** ***
Huom: Korkeuksien jotka ovat alle 3 ei tarvitse toimia!
Tässä tehtävässä luodaan seuraavanlainen numerovisa:
Arvaa luku: 73 Luku on pienempi, tehtyjä arvauksia: 1 Arvaa luku: 22 Luku on suurempi, tehtyjä arvauksia: 2 Arvaa luku: 51 Luku on suurempi, tehtyjä arvauksia: 3 Arvaa luku: 62 Luku on suurempi, tehtyjä arvauksia: 4 Arvaa luku: 68 Luku on suurempi, tehtyjä arvauksia: 5 Arvaa luku: 71 Luku on pienempi, tehtyjä arvauksia: 6 Arvaa luku: 70 Onneksi olkoon, oikein arvattu!
Tehtävänannon mukana tulevassa ohjelmassa tulee mukana komento arvoLuku
, joka arpoo luvun suljetulta väliltä [0, 100] (0 ja 100 ovat myös mahdollisia). Toteuta ohjelma jossa arvataan arvottua lukua kerran. Ohjelman tulee tulostaa joko "Luku on pienempi", "Luku on suurempi" tai "Onneksi olkoon, oikein arvattu!" riippuen käyttäjän antamasta luvusta.
Arvaa luku: 12 Luku on suurempi
Arvaa luku: 66 Luku on pienempi
Arvaa luku: 42 Onneksi olkoon, oikein arvattu!
Lisää ohjelmaan toiminnallisuus jossa arvausta tehdään toistuvasti kunnes käyttäjä syöttää oikean numeron. Huomaa, että sinun tulee arpoa numero komentoa arvoLuku
ennen toistolauseketta. Miksi? Mitä tapahtuu, jos luku arvotaan toistolausekkeen sisällä?
Alla olevassa esimerkissä kutsu komentoon arvoLuku
palautti arvon 83.
Arvaa luku: 55 Luku on suurempi Arvaa luku: 85 Luku on pienempi Arvaa luku: 77 Luku on suurempi Arvaa luku: 81 Luku on suurempi Arvaa luku: 83 Onneksi olkoon, oikein arvattu!
Lisää ohjelmaan kokonaislukutyyppinen muuttuja, jonka avulla pidetään kirjaa tehtyjen arvausten määrästä. Tulosta arvausten määrä aina arvauksen yhteydessä.
Arvaa luku: 55 Luku on suurempi, tehtyjä arvauksia: 1 Arvaa luku: 85 Luku on pienempi, tehtyjä arvauksia: 2 Arvaa luku: 77 Luku on suurempi, tehtyjä arvauksia: 3 Arvaa luku: 81 Luku on suurempi, tehtyjä arvauksia: 4 Arvaa luku: 83 Onneksi olkoon, oikein arvattu!
Käytämme tällä kertaa robottia viivataiteen luomiseen. Käytössä olevat komennot ovat Ohjain.kaynnista()
, Ohjain.sammuta()
, Ohjain.vasen()
, Ohjain.oikea()
ja Ohjain.liiku()
, joiden lisäksi yksittäisen askeleen odotusajan voi asettaa komennolla Ohjain.asetaOdotusaika(int millisekuntia)
.
Tämän tehtäväsarjan lopussa sinulla on koodi, jolla voit yhdellä metodikutsulla luoda esimerkiksi seuraavanlaisen kuvion.
Aloitetaan.
Toteuta metodi public static void liikuMonta(int montakoAskelta)
, joka siirtää robottia halutun määrän askelia siihen suuntaan, mihin robotti osoittaa. Esimerkiksi metodikutsu liikuMonta(5);
siirtää robottia siten, että lopputila on seuraavanlainen.
Toteuta metodi public static void piirraNelio(int sivunPituus)
, joka piirtää annetun kokoisen neliön (parametri sivunPituus kertoo yksittäisen sivun pituuden). Hyödynnä tässä edellisessä osassa tehtyä metodia liikuMonta
.
Metodikutsun piirraNelio(8);
tulee siirtää robottia siten, että lopputilanne on seuraavanlainen. Huomaa, että aina kun sivu on valmis, robotti kääntyy oikealle.
Toteuta seuraavaksi metodi public static void sisakkaisetNeliot(int montako)
, joka piirtää sisäkkäisiä neliöitä. Suurimman neliön sivun pituus on montako
-parametrille annettava arvo, ja pienimmän neliön sivun pituus on yksi.
Alla olevassa kuvassa metodia on kutsuttu parametrilla 10 (sisakkaisetNeliot(10);
)
Hyödynnä tässä aiemmin toteutettua metodia piirraNelio
.
Toteuta seuraavaksi metodi rajatutSisakkaisetNeliot(int suurin, int pienin);
sisäkkäisten neliöiden piirtämiseen. Tämä metodi saa parametrina kaksi arvoa, joista ensimmäinen kertoo suurimman piirrettävän neliön sivun pituuden, ja toinen kertoo pienimmän piirrettävän neliön sivun pituuden.
Alla olevassa kuvassa metodia on kutsuttu parametreilla 8 ja 4 (rajatutSisakkaisetNeliot(8, 4);
). Huom! Kuvassa on viisi neliötä (ja rho-botti, jota jotkut voisivat väittää neliöksi)!
Kun metodi rajatutSisakkaisetNeliot
toimii, muuta edellisessä tehtävässä olevan sisakkaisetNeliot
-metodin toimintaa siten, että se kutsuu tässä tehtävässä toteutettua metodia.
Toteuta metodi public static void viivakimara(int koko)
, jonka avulla voit piirtää jonkun mielekkään kuvion (voit pyrkiä esimerkiksi alla olevaan kuvaan). Toteuta viivakimara siten, että kuvat ovat erilaisia eri parametrin koko arvoilla.
Eeppisimmät viivakimarat tulevat näkyville vielä nimeämättömään paikkaan.