wiki:k2015/demot/demo10
Last modified 2 years ago Last modified on 2015-03-20 12:14:46

Demot » Demo 10, 23.3.2015

PP

(näistä saa pisteitä vain käymällä PP-ryhmässä)

PP-tehtävät 20.3 PP6

Oppimistavoitteet

Tämän demokerran jälkeen

  • muistat mitä rekursio tarkoittaa ja miten tehdään rekursiivinen funktio
  • osaat soveltaa silmukoita kombinaatiotehtävään
  • olet tutustunut poikkeuksiin (Exception) ja poikkeusten käsittelyyn

Pisteyttäminen (UUSI!)

Pisteyttämisessä on ollut jonkin verran epäselvyyksiä ja avoimia kysymyksiä, joten tässä tälle kerralle selkeät säännöt itsearvion tekemiselle. Kahden tai useamman pisteen tehtävissä luonnollisesti skaalaat tämän ohjeen asteikkoon sopivaksi.

Tärkeää! Jos ohjelma ei käänny, niin se ei ole palautuskelpoinen. Tästä lähdetään liikkeelle:

  • Ohjelma kääntyy ja tekee sitä mitä pitää: 0.6 p.

Ja sitten jos tuo ylläoleva on kunnossa niin:

  • Dokumentaatio kunnossa (nimi, versio, summary- ja parametri-dokumentaatiot, ym.) : + 0.2 p.
  • Luokan, muuttujien ja aliohjelmien nimet harkittuja ja kunnossa, ja koodi sisennetty oikein: + 0.2 p.

Kuitenkin, hyvästä yrityksestä annetaan myös pisteitä. Sovella silloin tuota annettua skaalaa omantuntosi mukaan. Mutta vaikka ohjelmasi ei tekisikään täydellisesti sitä mitä pyydettiin, niin sen täytyy kääntyä, ja ilman muuta dokumentaatio ja nimeäminen voi olla kunnossa tästä huolimatta.

Demojen palauttaminen

Jos sinulla on samassa .cs-tiedostossa usean tehtävän vastaus, niin voit laittaa tehtävän kohdalle esim. 1-2 (ja tietenkin vastaava määrä pisteitä), tai voit palauttaa saman tiedoston useammalla eri rivillä.

Tehtävä 1-2

M: 22. Rekursio. Katso Sierpinskin kolmio -luentoesimerkin mallia rekursiivisesta kolmion piirtämisestä. Tee mallia muokaten ohjelma, joka piirtää puu.png -kuvan kaltaisen puun rekursiosta:

 /// <summary>
 /// Tehdään pallo, ja sen yläpuolelle kaksi muuta palloa
 /// rekursiivisesti.
 /// </summary>
 /// <param name="peli">peli johon pallo lisätään</param>
 /// <param name="x">Pallon kp x-koordinaatti</param>
 /// <param name="y">Pallon kp y-koordinaatti</param>
 /// <param name="sade">Pallon sade</param>
 /// <param name="suunta">Suunta radiaaneina</param>
 public static void Pallo(Game peli,double x, double y, 
                          double sade, double suunta)
 {
    // pallo pisteeseen (x, y)
    // jos pallon sade < PIENIN_SADE lopeta

    // määrittele uusi säde itse ...
    double r = sade * ???;
    // määrittele suunnat itse ...
    double vasenSuunta = suunta + ???;
    double oikeaSuunta = suunta - ???;

    Pallo(peli, x + Math.Cos(vasenSuunta) * (sade + r),
                y + Math.Sin(vasenSuunta) * (sade + r),
                r, vasenSuunta);

    Pallo(peli, x + Math.Cos(oikeaSuunta) * (sade + r),
                y + Math.Sin(oikeaSuunta) * (sade + r),
                r, oikeaSuunta);
}

Hyvä alkukulma piirtämiseen on vaikkapa pi/2 (saat piin arvon kirjoittamalla Math.PI). Pallon säteeksi voit antaa vaikka 100. Kokeile vaihdella suuntaa ja sädettä muuttavia vakioita ja katso miten ne vaikuttavat kuvaan. Huom! Tässä ei piirretä Canvakselle, vaan tehdään ihan "normaaleja" GameObject-olioita.

Tehtävä 3

M: 23. Dynaamiset tietorakenteet. Tee lotto-ohjelma, joka arpoo 7 numeroa ja 3 varanumeroa 39:stä. Vinkki:

public static void Main(String[] args) {
     List<int> pallot = new List<int>();
     // täytä pallot-lista numeroilla 1-39, esim neljäs pallo
     // lisättäisiin näin: pallot.Add(4);
     // sotke pallot (ota mallia edellisistä demoista missä 
     // sotkettiin taulukko)
     // tulosta 7 ekaa palloa
     // tulosta 3 seuraavaa palloa
}

Sotkemisen voit tehdä myös lisäämällä projektin referensseihin Jypeli.dll:n ja sitten

Jypeli.RandomGen.Shuffle(pallot);

Tehtävä 4

Tee ohjelma joka arpoo satunnaisia sanoja listaan. Satunnaisten sanojen tekemiseen voit käyttää PP2-tehtävässä annettua SatunnainenSana-funktiota (Avaa koodi tästä.). Käyttäjältä kysytään sallitut merkit, sanojen minimi- ja maksimipituudet, ja arvottavien sanojen määrä. Ohjelma tulostaa arvotut sanat. Sitten kysytään käyttäjältä merkkijonoa, jonka perusteella sanoja poistetaan listasta. Lopuksi tulostetaan poistetut, sekä jäljelle jääneet. Alla tulostusesimerkki.

Anna kirjaimet joista arvotaan sanoja > ak$V
Minimipituus > 4
Maksimipituus > 10
Määrä > 5
ka$aa$Vakk
a$$Va
V$$Vaa$
V$a$a
$aakaaa
---
Mitä pitää löytyä, että poistetaan > aa
Poistettiin seuraavat:
ka$aa$Vakk
V$$Vaa$
$aakaaa
Jäljelle jäivät:
a$$Va
V$a$a

Tehtävä 5

M: 16. Toistorakenteet. Erilaisten 7 numeroa sisältävien lottorivien määrä saadaan binomikertoimen kaavasta:

Katso: http://fi.wikipedia.org/wiki/Kombinaatio

kaava 1      kaava 2              kaava 3

 39           39!            33*34*35*36*37*38*39 
(   )  = --------------  =  ---------------------- = 15380937
  7       7! * (39-7)!           1*2*3*4*5*6*7

Tulos voidaan laskea käyttämällä long -tyyppisiä lukuja. Tee funktio long NYliK(int n, int k) jonka kutsulla NyliK(39, 7) saat mainitun tuloksen. Tulosta ei voi laskea keskimmäisestä kaavasta 2, koska 39! ylittäisi reilusti pitkienkin (long) kokonaislukujen lukualueen.

Vinkki: Tässä tehtävässä ei tarvita listoja tms., pelkästään kerto- ja jakolaskuja sekä silmukoita. Vastaus on nätimpi jos avuksi kirjoittaa yhden pienen aliohjelman.

Tehtävä 6

M: 24. Poikkeukset. Kirjoita funktio MuutaJono(String s, double oletus), jota voidaan käyttää seuraavasti.

public static void Main(string[] args)
{
  double d1 = MuutaJono("12,3", 0.0); 
  // desimaalimerkki käyttöjärjestelmän mukaan, 
  // oletuksena suomenkielisissä windowseissa se on pilkku.
  double d2 = MuutaJono("12,3e", 0.0);
  Console.WriteLine("{0:0.00}, {1:0.00}",d1,d2); // 12,30 0,00 
  Console.ReadKey();
}

Eli funktio yrittää poimia annetusta merkkijonosta liukuluvun (double) ja palauttaa sen. Mikäli tämä ei onnistu, palauttaa se oletusarvon. Funktiolle on oikeassa elämässä käyttöä koska käyttäjältä saatu syöte on aina merkkijono ja se pitää pystyä muuttamaan reaaliluvuksi laskemista varten. Tuo desimaalierotin on vaikeampi. Parse käyttää sitä erotinta, mikä on järjestelmään asetettu. Oikeasti pitäisi siis vielä osata tulkita oikealla tavalla riippumatta siitä, antaako käyttäjä pilkun vai pisteen. Tässä tehtävässä tuosta ongelmasta ei tarvitse välittää vaan riittää yllä olevaan esimerkkiin käsin vaihtaa piste pilkun tilalle jos järjestelmässäsi on piste desimaalierottimena (C#-koodin vakioissahan se on aina piste).

Kun toteutat funktiota MuutaJono, käytä hyväksi double-luokan funktiota double.Parse ja sitä, että jos muuttaminen ei onnistu, Parse heittää poikkeuksen.

V1

Tee Ville-tehtävät: 8.1-8.5. Muista: Villen käyttöohje ja Ville-tehtävien palauttamisohjeet.

TDD1

Jos tarkistat vähintään kahden funktion toiminnan automaattisella testillä (ComTest), saat merkitä yhden lisäpisteen. Palauta DemoWWW:ssä tekstitiedosto TDD.txt (jonka siis arvostelet yhden pisteen arvoiseksi), missä kerrot minkä tehtävän ja minkä funktion/funktioiden toiminnan testasit. Voit antaa samassa tiedostossa palautetta ja kehitysehdotuksia Comtestin käytöstä. Mikäli ComTest ei toimi yliopiston mikroluokissa, tarkista että ComTest haetaan oikeasta paikasta: Valitse Visual Studiossa Tools -> ComTest -> Options. Esiin tulee ComTest Plugin Options. Tarkista, että Path to ComTest.jar executable kentässä on N:\bin\ComTest.jar ja ole yhdistänyt koneesi N-verkkolevyyn.

B1-2

Avaa sivu http://openpages.nordea.com/fi/lists/currency/commercialExchangeRateFI.action?language=fi ja klikkaa sivun oikeasta yläkulmasta "Lataa Excel-tiedosto". Tallenna .csv-tiedosto koneellesi nimellä "valuutat.csv". Lisää Visual Studion projektiisi uusi tiedosto klikkaamalla projektin nimen päällä hiiren kakkosnäppäimellä Add -> Existing Item). Laita tiedosto myös kopioitumaan bin-hakemistoon klikkaamalla tiedoston päällä hiiren oikealla -> Properties -> Copy to output directory -> Always copy. Tiedosto voidaan nyt lukea seuraavasti: Lisää ensin Using-lauseisiin lause

using System.IO;

Sitten Main-pääohjelmaan (tai johonkin muuhun aliohjelmaan)

string[] valuuttalista;
try
{
    valuuttalista = File.ReadAllLines("valuutat.csv");
}
catch (IOException ex)
{
    Console.WriteLine("Virhe: " + ex.Message);
    return;
}

Pyydä käyttäjältä jokin valuuttatunnus, ja tulosta annetun valuutan tiedot ruudulle. Ohjelma päättyy, kun käyttäjä antaa tyhjän syötteen. Vinkki: String.Split

B3

Tutki miten C#:issa toimii BigInteger -luokka ja tee NYliK(int n,int k) sen avulla. Tee siis tehtävää 4 vastaava toteutus erityyppisellä kokonaisluvulla. Jos jossakin sanotaan että Assembly XXX.dll, niin tuon Assembly voi joutua lisäämään projektiin hiiren oikealla ja Add Reference ja sitten kohta .NET.

G1-2

Tutki miten C#:ssa voidaan lukea syötettä WWW-osoitteesta ja tee tehtävä B1-2 niin, että tiedot luetaan suoraan netistä.

G3-4

PNS: Pienimmän neliösumman sovitus on eräs tapa laskea eräänlainen "keskiluku" tai trendi aineistolle. Esimerkiksi meillä on havaintopisteitä, joiden periaatteessa pitäisi muodostaa "suora". Laskemalla PNS-suoran (y = a + bx) kertoimet a ja b voimme piirtää aineistoa parhaiten kuvaavan suoran. Katso http://mathworld.wolfram.com/LeastSquaresFitting.html kertoimien laskukaavat (12) ja (14) ja tee ohjelma, joka piirtää aineiston ja sitä kuvaavan PNS-suoran. Aineisto piirretään tämän pohjatiedoston: Kuvaaja.cs avulla, eli voit käyttää siellä olevaa koodia pohjana itse aineiston piirtämiseen. Suora piirretään Paint -metodissa kutsumalla canvas.DrawLine-metodia. Esimerkki: pns.png (tuossa Javalla tehdyssä kuvassa pallot eivät ole täytettyjä, sitä ei tarvitse yrittää).

G5-6

Euler problem 67. Laskun pitää mennä alle minuuttiin. Yksi lisäpiste jos lasku menee "erittäin nopeasti" (luokkaa millisekunteja.)