wiki:s2014/demot/demo10
Last modified 3 years ago Last modified on 2014-11-13 14:59:11

Demot » Demo 10, 17.11.2014

Vaikeaa, vastaa kurssin välikyselyyn

Tarvitsemme tietoa siitä, mitkä ovat kurssin vaikeudet suhteessa siihen, mitä kurssilla on tehty. Kysely toimii samalla itsearviona. Siksi kurssista on Korpissa välikysely. Täytä kysely ja tee tiedosto vaikeaa.txt, johon kerrot, mikä oli vaikeaa tällä demokerralla. Palauta yhtenä DemoWWW:n "tehtävänä" K1 ja merkitse 1p, jos olet vastannut itse kyselyyn tällä kertaa (mutta et aikaisemmalla kerralla). Muuten laita 0.2 pistettä.

Demojen palauttaminen

Demot palautetaan viimeistään maanantaina klo 11:00 mennessä kurssin NettiDemoWWW:hen https://www.mit.jyu.fi/demowww/ohj1/. Voit palauttaa osan tai kaikki tehtäväsi etukäteenkin ja täydentää vastauksia määräaikaan mennessä. Jos sinulla on samassa .cs-tiedostossa usean tehtävän vastaus, niin voit laittaa tehtävän kohdalle esim. 3-4, tai voit palauttaa saman tiedoston useammalla eri rivillä.

Tehtäväkerran 2 pakollista minimiä saa valita mitä tahansa tehtävistä 1-6, B tai G.

V1

Tee Ville-tehtävät: 8.1-8.5. Tästä Villeen 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 olet yhdistänyt koneesi N-verkkolevyyn.

Tehtävä 1-2. Rekursiivinen pallokuva

M: 21. Rekursio. Katso 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 vSuunta = suunta + ???;
    double oSuunta = suunta - ???;

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

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

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 : Jos tehtävä ei aukea, älä aloita tällä tehtävällä, vaikka tämä periaatteessa onkin helppo tehtävä. Tehtävän ymmärtämiseksi on lähes pakko että on katsonut luennon 19.

Tehtävä 3. Lotto

M: 22. 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 numeroilla 1-39, esim: 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 (Browse ja löytää mistä tahansa Jypeli-projektin bin hakemiston alta, myös sieltä mihin olet Jypelin asentanut) ja sitten

Jypeli.RandomGen.Shuffle(pallot);

Tai voit ottaa Demo 9 vastauksista Sotke.cs ja käyttää hieman muutettuna sen Shuffle-aliohjelmaa.

Tehtävä 4-5. n yli k

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. Poikkeukset

M: 23. 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);
  double d3 = MuutaJono("kana", 3.1);
  Console.WriteLine("{0:0.00}, {1:0.00}, {2:0.00}",d1,d2,d3); 
  // tulostaa: 12,30 0,00 3,10
  Console.ReadKey();
}

Eli funktio yrittää poimia annetusta merkkijonosta liukuluvun (double) ja palauttaa sen. Mikäli tämä ei onnistu, palauttaa se oletuksen. 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 merkkijonoissa "12,3" 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.

B1-2. Valuuttakurssit

Avaa sivu

ja kopioi leikepöydälle kaikki valuuttakurssit. Siis vain ne rivit, joilla on tietoja valuutoista. Lisää Visual Studion projektiisi uusi tekstitiedosto, liitä valuuttakurssit tekemääsi tekstitiedostoon ja tallenna se nimellä valuutat.txt. Muokkaa tiedosto seuraavan näköiseksi:

EUR Euroopan valuuttayksikkö 1,000000	1,000000	1,000000
USD Yhdysvaltain dollari     1,242400	1,222900	1,261900
JPY Japanin jeni             143,880000	141,280000	146,480000
...

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 Mainiin (tai johonkin muuhun aliohjelmaan)

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

Tee ohjelma, joka kysyy silmukassa käyttäjältä valuuttatunnuksen, ja sitten tulostaa annetun valuutan tiedot ruudulle. Ohjelma päättyy, kun käyttäjä antaa tyhjän syötteen. Eli tyyliin:

Anna valuutta >USD[ret]
USD Yhdysvaltain dollari     1,242400	1,222900	1,261900
Anna valuutta >KWD[ret]
KWD Kuwaitin dinaari         0,361800	0,356800	0,366800
Anna valuutta >[ret]
Kiitoksia käytöstä!

B3-4. Rekursiivinen puu

M: 22. Rekursio: Katso mallia rekursiivisesta kolmion piirtämisestä suoraan canvakselle. Tee mallia muokaten ohjelma, joka piirtää puu.png -kuvan kaltaisen puun käyttäen rekursiota:

 * Puun yksi oksa ja kolme muuta rekursiivisesti
 *  x oksan alkupiste
 *  y oksan alkupiste
 *  d oksan suunta radiaaneina
 *  l oksan pituus
 *
 oksa( x, y, d, l) 
     viiva pisteestä (x,y) pisteeseen (x+l*cos(d),y+l*sin(d)) 
     jos l < 2 lopeta
     oksa(x+l*cos(d),y+l*sin(d),d+0.6,l*0.6);
     oksa(x+l*cos(d),y+l*sin(d),d-0.6,l*0.6);
     oksa(x+l*cos(d),y+l*sin(d),d,l*0.3);

Hyvä alkukulma piirtämiseen on vaikkapa pi/2 ja pituus vajaa puolet ikkunan korkeudesta. Tee ohjelmaan näppäinohjaus, jolla voit vaikuttaa kulman muutoskertoimeen 0.6, pituuden muutoskertoimeen 0.6 (eri luku kuin kulmalle) sekä keskioksan pituuden kertoimeen 0.3.

B5. BigInteger

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 Assemblyn voi joutua lisäämään projektiin hiiren oikealla ja Add Reference ja sitten kohta .NET.

G1-2. Valuuttakurssit netistä

Tutki, miten C#:ssa voidaan lukea syötettä WWW-osoitteesta ja tee tehtävä B1-2 niin, että tiedot luetaan suoraan netistä. Muuten ohjelma toimisi samalla tavalla käyttäjän kannalta.

G3-4. PNS

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 kuten demo 8 Kuvaaja.cs, 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ää).

PP

PP-tehtävät (Pahasti Pihalla) on tarkoitettu niille, joilla on vaikeuksia aivan perusasioissa. Tarkoitus on, että nämä ovat helpompia tehtäviä (mutta yhdessä on monta tehtävää), joiden avulla pakollisen kahden tehtävän saaminen on mahdollista. PP-tehtävät eivät ole tarkoitettu niille, jotka ovat tehneet säännöllisesti 4 tai enemmän tehtäviä/kerta.

PP1

  1. Tee for-silmukka, joka tulostaa seuraavaa:
    0
    2
    4
    6
    ...
    98
    
  2. Lataa itsellesi Laskuharjoituksia.cs tiedosto ja täydennä aliohjelmat siten, että pääohjelma tulostaa konsoliin annettujen lukujen tulojen summan 2 * 3 + 4 * 7.
  3. Tee (funktio)aliohjelma, joka laskee (ja palauttaa) tuotteen alennetun hinnan kun viedään parametrina alkuperäinen hinta ja alennusprosentti. Tee pääohjelma, josta kutsut tekemääsi aliohjelmaa ja tulostat sen antaman arvon.

PP2

  1. Tee for-silmukka, joka tulostaa seuraavaa:
    1
    3
    5
    7
    ...
    99
    
  2. Tee aliohjelma LaskeMatkanKesto, joka laskee kuinka kauan jokin matka kestää annetulla matkan pituudella ja keskinopeudella. Pääohjelma voisi näyttää tältä:
    public static void Main(string[] args)
    {
        double matkanPituus_km = 124.5;
        double keskiNopeus = 120;
    
        double matkanKesto = MatkanKesto(matkanPituus_km, keskiNopeus);
        Console.WriteLine("Matka kestää " + matkanKesto + " tuntia");
        Console.ReadKey();
    }
    
  3. Tee (funktio)aliohjelma joka laskee (ja palauttaa) tuotteen alkuperäisen hinnan kun viedään parametrina alennettu hinta ja alennusprosentti. Tee pääohjelma, josta kutsut tekemääsi aliohjelmaa ja tulostat sen antaman arvon.