# ohj1g

Palautus viimeistään: klo 11:00 ma 6.11.2017
Katso luennot-sivulta luennot 17 ja 18.

Ohjelmointi 1, syksy 2017 / Demo 9

# tunnit

Demot palautetaan viimeistään maanantaina klo 11:00 mennessä. Voit palauttaa osan tai kaikki tehtäväsi etukäteenkin ja täydentää vastauksia määräaikaan mennessä.

# vdr1
Palautustilaisuuden videot Demoryhmä 1
# vdr2
Palautustilaisuuden videot Demoryhmä 2

TÄRKEÄÄ: Kokeeseen ilmottautuminen

Korpissa on kurssin sivulla ilmoitettu kurssin tentit. Käy ilmottautumassa tenttiin ja lukemassa tarkemmat ohjeet tentin järjestelyistä tentti-sivulta. Ja erityisesti ruksi kurssin Korppi-sivulla mihin aikaan voit tulla 30.11 tenttiin.

Oppimistavoitteet

# Oppimistavoitteet

Itsearvio A1 (0p mutta pakollinen)

Jollet tehnyt jo maanantain demopalautuksessa, niin täytä edellisen (esim. demo1:n arvion demo 2 kerralla) kerran itsearviolomake.

Kirjoita alla olevaan tekstilaatikkoon kunkin edellisen demokerran tehtävän kohdalle === katkoviivan alle

  • millainen oli oma vastauksesi verrattuna malliin/demojen palautuksessa käsiteltyyn tehtävään
  • olisiko omassa vastauksessasi pitänyt olla jotakin enemmän/vähemmän
  • jos et ollut tehtävää tehnyt, niin miksi?
  • jos et ollut tehtävää tehnyt, niin mitä ymmärsit vastaavasta mallivastauksesta tai demojen palautuksessa käsitellystä vastauksesta
  • osaisitko nyt tehdä vastaavan tehtävän ja miten, kun olet mallin nähnyt?

Erityisesti täytettävä perustehtävien "TX" osalta, missä X on jokin numero. Sekä kaikkien muiden, mitä olet tehnyt (mahdollisesti esim. Tauno, B-G). Toki mielellään ymmärtämisen osalta myös tehtävän B osalta, vaikket olisi tehnytkään.

Lisää tarvittavat otsikkorivit lopuille tehtäville samaan tyyliin kuin alla on tehty.

# itsearvio
==================================================
Tauno T1
==================================================


==================================================
Tauno T2
==================================================


==================================================
Ville V1
==================================================



==================================================
T1
==================================================




==================================================
T2
==================================================

 

Mistä saisi näkyviin valintakoetehtävän vastaukset?

VL: demojen palautusvideoilta.

31 Oct 17 (edited 01 Nov 17)
# itsearvio4

Voit palauttaa myös kuvan paperille kirjoitetusta

 

# kysely2

Kysely 2

Vastaa oppimisen tutkimuskyselyyn. Varaa tähän 20-30 min aikaa jotta ehdit vastata kaikkiin kysymyksiin kerralla.

# kysely

Analysoi lyhennettynä vastauksia kyselyyn

 

Video 1

Muista että voit saada demopisteitä myös indeksoimalla luento/demovideoita, ks: videohakemisto. Lisää vähintään 3 linkkiä ja kerro mitkä linkit lisäsit. Jatkossa voi joka demokerralle merkitä aina vähintään 3:sta linkistä yhden demotehtävän.

# video1

 

V1

Tällä kertaa ei tule uusia Ville-tehtäviä. Jos sinulla on tekemättä silmukka- ja/tai taulukkotehtäviä (tai muita joita et aikaisemmin ymmärtänyt), tee niitä 5 kappaletta. Tästä Villeen Muista: Villen käyttöohje ja Ville-tehtävien palauttamisohjeet.

# villev1

 

# tauno1

Tauno (1p)

Tee funktio, joka laskee taulukosta suljetulla välillä 0-10 olevien lukujen keskiarvon. Jotta funktio olisi yleiskäyttöisempi, viedään sille parametrina myös tuo alaraja (esimerkissä 0) ja yläraja (esimerkissä 10). Mikäli keskiarvoa ei voi laskea, palautetaan arvo ala-1. Kirjoita myös testejä ainakin 5 kpl erilaisille taulukoille ja rajoille.

Virheilmoitusten tulkitseminen

# tauno
//
    public static double Keskiarvo(int[] taulukko, int ala, int yla)
    {
       // Täydennä aliohjelma valmiiksi
    }

 

Miten tohon konsoliin tulevaa virheilmoitusta pitäisi oikein tulkita? Tarkoittaako "10 piti: 98.000 -> -1.000 {12,0,42,14,99,12,55} 99 0", että 98 on oikein vai -1 on oikein?

VL: lisäsin tulkintaohjeen

01 Nov 17 (edited 01 Nov 17)

TDD1

Tehtävät, joissa on Test-painike, tulee testata Comtestillä, jotta saa täydet pisteet. 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.

Eli tällä kertaa testit eivät ole bonusta vaan tehtävään kuuluva osa. Piirtotehtäviä (portaat yms) on hankala testata ja sitä ei tehdä tällä kurssilla.

# pohja

Pohjatiedostot varsinaisille tehtäville

  • Tarvitaan tehtävissä 5,6-7,B1-3

  • Mono-versioita (Xamarin, Linux) käyttävät joutuvat kuvankäsittelytehtävissä lisäämään Begin-metodin alkuun Image.SetLineCorrection(1); ja kokeilemaan toimiiko tuo parametrilla 0 vaiko 1 (vai ei kummallakaan). Raportoikaa viereen kommentilla kuinka käy.

Xamarinissa saattaa tulla virheilmoitus rivinvaihdoista (line endings). Valitse tässä tilanteessa: Convert all files to UNIX line endings

Mikäli Kuva-tyypistä tulee virheilmoitus, niin siihen saattaa auttaa kun lisää Ohjelma.cs-kooditiedostoon

using demo9;

Kokeile ajaa eri ohjelmia. Palapelissä hiiren klikkaus siirtää palaa ja Kuva-ohjelmassa tulee erilaisia kuvia.

Seuraava ongelma on tullut ainakin XP-koneiden kanssa, mulla itselläni ei esim. Win7:lla: Mikäli Palapeli-projekti valittaa ajettaessa, ettei löydä kuvaa, klikkaa Solution Explorerissa ko. projektia hiiren oikealla -> Project Dependencies ja laita ruksi projektin kohdalle. Vastaavasti Kuva-projektia ajettaessa ruksin voi joutua ottamaan pois. Ongelman voinee kiertää niinkin, että tekee molempiin projekteihin oman Content-hakemiston ja kopioi niihin saman sisällön.

Tehtävä 1. Taulukon nousevat

M: 15. Taulukot. Tee aliohjelma PisinNouseva, jolle annetaan parametrina kokonaislukutaulukko ja se palauttaa kokonaisluvun. Aliohjelma palauttaa pisimmän taulukosta löytyvän aidosti nousevan osajonon pituuden. Esimerkiksi jos taulukon alkiot ovat 2,3,4,1,2,0,1,2,5,5,7, niin palautetaan 4 (eli 0,1,2,5 muodostavat 4 lukua pitkän aidosti nousevan osajonon). Aloita tekemällä aliohjelman esittelyrivi ja lyhin mahdollinen toteutus aliohjelmalle. Myös testit kannattaa kirjoittaa ja ehkä jopa ennen itse aliohjelman kirjoittamista (=TDD). Vinkkinä kannattaa katsoa Demo 8 Tauno-tehtävä sekä demonpalautusvideo Valintakoetehtävän käsittelystä.

# v1
Katso video: Taulukon nousevat Luento 18 2015 – 15m49s (1m1s)
# pisinOsajono

 

Oljenkorsi 1: harjoittele

Tehtävä 2*. Portaat ylös

Palataan hetkeksi kurssin alkupuolen laatikkotehtävään. Muuta ohjelmaa siten, että PiirraLaatikko-aliohjelmalle viedään Vector-olio kahden reaaliluvun sijaan. Tämä vektori toimii piirrettävän neliön vasemman alakulman merkkinä. Aliohjelma piirtää neliön ja palauttaa sitten piirtämänsä neliön oikean yläkulman koordinaatin. Nyt seuraavan Neliön piirtäminen on yksinkertaista koska se voidaan aloittaa edellisen kutsun palauttamasta paikasta. Mieti, mitä tulee ???-merkittyihin kohtiin.

Kuva siitä, miltä toimiva ohjelma näyttää ruudulla: Mallikuva

# v2
Katso video: Portaat ylös Luento 18 2015 – 16m50s (2m42s)

Oljenkorsi 1

Oljenkorsi 2

# portaatylos
    public override void Begin()
    {
        Level.Background.Color = Color.Black;
        Vector piste = new Vector(0, 0);
        piste = PiirraLaatikko(this, piste);
        piste = PiirraLaatikko(this, piste);
        piste = PiirraLaatikko(this, piste);
        PhysicsObject pallo = new PhysicsObject(5, 5, Shape.Circle);
        Add(pallo, 1);
        pallo.Color = Color.Red;
        Camera.ZoomToAllObjects(100);
    }


    /// <summary>
    /// Aliohjelma piirtää ruutuun yhden neliön, jonka
    /// sivun pituus on 80 ja vasemman alakulman koordinaatti p.
    /// </summary>
    /// <param name="peli">Peli, johon neliö piirretään</param>
    /// <param name="p">Neliön vasemman alanurkan koordinaatti.</param>
    /// <returns>Neliön oikean ylänurkan koordinaatti</returns>
    public static ??? PiirraLaatikko(???)
    {
        double s = LAATIKON_KOKO;
        GameObject nelio = new GameObject(s, s, Shape.Rectangle);
        nelio.Position = ???
        peli.Add(nelio);
        ???
    }

 

Miten saa sen oikean yläkulman koordinaatin ilman neliöjuurta?

VL: Helposti leveyden ja korkeuden avulla.

03 Nov 17 (edited 03 Nov 17)

Tehtävä 3. Portaat ylös ja alas

Jatka edellistä tehtävää siten, että jos pääohjelmaa muutetaan seuraavasti:

public override void Begin()
{
    Camera.ZoomToLevel();
    Vector piste = new Vector(0, 0);
    piste = PiirraLaatikko(this, piste);
    piste = PiirraLaatikko(this, piste);
    piste = PiirraLaatikko(this, piste);
    piste -= new Vector(0,LAATIKON_KOKO); 
    piste = PiirraLaatikkoAlas(this,piste);
    piste = PiirraLaatikkoAlas(this,piste);
}

niin ohjelma piirtää viisi neliötä, joista keskimmäinen on korkeimmalla. PiirraLaatikkoAlas saa parametrinaan uuden neliön vasemman ylänurkan koordinaatin ja palauttaa piirtämänsä neliön oikean alanurkan koordinaatin.

Mallikuva
Mallikuva

HUOM! LAATIKON_KOKO on määritelty luokan vakioksi ja sitä tulee käyttää tehtävässä.

Muokkaa vielä niin, että pääohjelmasta voidaan kutsua PiirraPortaat-aliohjelmaa, joka piirtää annetun määrän neliöitä ylöspäin ja sitten annetun määrän alaspäin. Sama kuva saataisiin siis kutsulla:

        public override void Begin()
        {
            Level.BackgroundColor = Color.Black;
            Vector piste = new Vector(0, 0);
            PiirraPortaat(this, piste, 3, 2);
            Camera.ZoomToAllObjects(100);
        }
# v3
Katso video: Portaat ylös ja alas Luento 18 2015 – 19m32s (1m30s)

HUOM! Anna itsellesi vain 0.5 p jos et tehnyt PiirraPortaat aliohjelmaa!

# portaatylosjaalas
    public override void Begin()
    {
        Level.Background.Color = Color.Black;
        Vector piste = new Vector(0, 0);
        piste = PiirraLaatikko(this, piste);
        piste = PiirraLaatikko(this, piste);
        piste = PiirraLaatikko(this, piste);
        piste -= new Vector(0,LAATIKON_KOKO);
        piste = PiirraLaatikkoAlas(this,piste);
        piste = PiirraLaatikkoAlas(this,piste);
        PhysicsObject pallo = new PhysicsObject(5, 5, Shape.Circle);
        Add(pallo, 1);
        pallo.Color = Color.Red;
        Camera.ZoomToAllObjects(100);
    }

    // TODO: Kopioi tähän edellisen tehtävän PiirraLaatikko
    // TODO: Jatka tekemällä PiirraLaatikkoAlas

 

Tehtävä 4*. Pisimmän sanan poistaminen

M: 23. Dynaamiset tietorakenteet. Pääohjelmassa on annettu lista sanoja. Tee testit ja aliohjelma, joka etsii listan pisimmän sanan. Pääohjelma tulostaa ensin listan kaikki sanat, pisimmän sanan ja poistaa sitten listasta KAIKKI tämän sanan esiintymät. (Ei ole tarkoitus käyttää RemoveAll-metodia)

# v4
Katso video: Pisimmän sanan poistaminen Luento 18 2015 – 21m2s (1m40s)
# poistapisin

 

Pääohjelmassa kutsutaan määrittelemätöntä aliohjelmaa "PoistaSanat". Pitääkö tehdä itse vai onko vahinko?

VL: ensin etsii ja sitten poistaa, eli on se poistaminenkin tehtävä.

29 Oct 17 (edited 31 Oct 17)

Tämän tehtävän tehtävänannossa oli epäselvää, pitääkö poistaa kaikki sanat, jotka ovat yhtä pitkiä kuin pisin.

VL: TÄMÄN sanan.

Tämä oli vain kohta, jossa tehtävänantoa on vaikea ymmärtää yksiselitteisesti, koska pisin sana ei ole yksiselitteinen käsite, jos on useita yhtä pitkiä sanoja.

02 Nov 17 (edited 03 Nov 17)

Ei mitään hajua miten etsiä pisintä sanaa. Olen kokeillut kaikenlaista epätoivoista.

VL: se on tehty kahdelle sanalla siellä demoissa jossa ekan kerran oli merkkijonoja. Ja silloin ainakin demonpalautuksissa myös käsiteltiin yhtäpitkien käsittelyperusteet.

03 Nov 17 (edited 03 Nov 17)

Onko PoistaSanat -aliohjelmassa ideana, että se modifioi sanat -listaa? Pääohjelma ei ainakaan näytä olettavan sen palauttavan uutta listaa, josta sanat olisi poistettu.

VL: eikös se silloin automaattsiesti implikoi sitä että muutos on tehtävä listaan.

04 Nov 17 (edited 04 Nov 17)

En saa tästä täysiä pisteitä. Miksi?

VL: Poistaminen toimii väärin. Eikä sulle ole sille edes testejä!

AM: On siellä yksi testi :)
VL: Poistamiselle ei ole ja se poistaa ihan liikaa sanoja. Jos annan sulla listan kissa koira kana ja sanon että poista kissa, niin en halua koiraa pois!

04 Nov 17 (edited 05 Nov 17)

Testit valittaa koko ajan että "Invalid expression term 'string'". Ne rivit joissa se valittaa siitä ei edes kuulu siihen testiin.

VL: sun testit on syntaktisesti ihan väärin. Ei listoja noin voi testata. Ja itse asiassa kun ei edes pitäisi palauttaa listaa. Oletko Visual Studiossa yrittänyt testata ja katsoa sitä syntyvää testitiedostoa, niin se aika hyvin näyttää missä on väärin. Lisäksi sun koodi on Tauno-vastaus ilman silmukkaa ja ei selviä jos sanoja on eri määrä kuin perustestissä.

05 Nov 17 (edited 05 Nov 17)

Silmukan sain helposti aikaan. Taunomainen vastaus oli siinä ihan vaan sen takia että halusin aluksi vaan saada tehtyä tehtävän jotenkin. Ainoa asia jonka nyt haluaisin tietää on että miten ne testit pitäs sitten oikeesti tehdä, Visual Studion avulla en saa muuta kuin valitusta syntax errorista ja sen semmoisesta. Joo, tiiän että ne testit ei oo varmaan syntaktisesti oikein mutta senpä takia juuri tarvitsisin tiedon siitä miten ne toimivat testit tehdään.

VL: Mitä funktio palauttaa? Mitä sille viedään paramterina. Testissä käytetty lause pitäisi voida sijoittaa pääohjelmaan kun === tilalla käytetään == merkkiä. Esim tyyliin: bool ok = Testattava(param) == tulos; Silloin näkee onko edes mahdollista että lause olisi syntaktisesti oikein.

05 Nov 17 (edited 05 Nov 17)

En keksi miksi ohjelma jättää listaan yhden kissan.

06 Nov 17

Vinkki: Testaamista varten katso luentomonisteen mainitusta kohdasta miten listoja testataan.

Tehtävä 5. Värien vaihtaminen

Kuvan värien muuntelu: Lue ohje. Katso esimerkistä: Kuva.cs miten piirretään kuvia. Ota kuvaksi vaikka: vesa.png. Tutustu huolella aliohjelmiin Harmaasavy, HarmaasavyTaulukolla ja Punaiseksi. Tee näitä matkien aliohjelma PoistaPunainen, jolle viedään parametrina Image-kuva ja raja-arvo jota enemmän kuvassa pitää olla punaisen osuutta jotta vastaava piste muutetaan harmaasävyksi. Kutsu Begin-metodista aliohjelmaa niin, että muutetaan harmaasävyksi kaikki ne pisteet, joissa punaista väriä on enemmän kuin 150. Huom! Suoraan pelkkää punaisen määrää vertaamalla ei oikeasti kaikki punainen katoa, mutta se riittää tähän tehtävään. Saa keksiä myös paremman ehdon jos haluaa :-)

Vaikuttaisi että Mono (eli mm. Xamarin) versioissa pitää Begin-metodin alkuun lisätä rivi:

  Image.SetLineCorrection(0); 

VL: Onko joku saanut Mäcissä toimimaan näitä kuvatehtäviä?

Toimii jos ottaa nyt alkuun lisätyn ohjeen mukaan cs-tiedostoista Mac-versiot.

01 Nov 17 (edited 04 Nov 17)

Linuxissa toimii kun laittoi Image.SetLineCorrection(0);

03 Nov 17

Huomatus väritiedon ottamisesta

# v5
Katso video: Värien vaihtaminen Luento 18 2015 – 22m42s (19m37s)
# poistaPunainen

Kopioi PoistaPunainen-aliohjelma kommentteineen tähän.

 

Tehtävä 6-7. Palapeli

Täydennä Palapeli.cs-tiedostosta aliohjelmat: LuoKuvat ja LisaaPalatRuutuun toimiviksi niin, että saat toimivan palapeli-ohjelman. Kokeile lisätä Contenttiin jokin muukin kuva ja kokeile toimintaa sillä.

Vaikuttaisi että Mono (eli mm. Xamarin) versioissa pitää Begin-metodin alkuun lisätä rivi:

  Image.SetLineCorrection(0); 

Mä onnistuin jotenkin hajottamaan oman koneeni visual studion ja saan virheilmoitusta: System.Drawing.dll'. Cannot find or open the PDB file. Tämä tulee muutaman muunkin dll tiedoston kohdalla. Ei auta vaikka luo uuden solutionin. En pysty nyt debuggerilla katsomaan noita tekemiäni silmukoita joten toiveissa olisi että ne käytäis huomenna demopalautuksessa läpi kun jäi vähän epävarma fiilis että onnistuiko ne.

05 Nov 17

Oljenkorsi 1

# LuoKuvat

Kopioi LuoKuvat -aliohjelma kommentteineen tähän.

 

# LisaaPalatRuutuun

Kopioi LisaaPalatRuutuun -aliohjelma kommentteineen tähän.

 

# konvo

B1-3. Konvoluutio

Konvoluutio: Sisätulo on kahden matriisin vastinalkioiden tulon summa. Liu'uttamalla painomatriisia kuvan päällä ja laskemalla aina vastaavasta kohdasta sisätulo ja laittamalla se jaettuna painomatriisin summalla, voidaan kuvalle tehdä useita yleisesti tarpeen olevia muunnoksia kuten reunaviivojen korostusta, terävöintiä tai pehmennystä.

Kokeilua varten jompikumpi alla olevista:

  • Työaseman Jar-versio:
    • lataa levylle konvo.jar

    • käynnistä konvo.jar klikkaamlla tai sen hakemistosta komentoriviltä kirjoittamalla

        java -jar konvo.jar
  • WWW-liittymä (toimii vain Firefox ja silläkin kikkailemalla):

Kokeiluversioissa voit kokeilla miten mikäkin matriisi vaikuttaa. Samalla voit kokeilla mitä vaikuttaa kuvien summaaminen tietyillä painoilla. Mallipohjassa Kuva.cs on vastaava ohjelma jossa on valmiina keskiarvosuodin 3x3 matriisilla. Sinun pitäisi täydentää keskeneräinen Muunna-aliohjelma valmiiksi.

VL: Tämä ei toimi Mäcissä jollei ei muuta itse kaikkia uint[,] taulukoita Color[,]-taulukoiksi ja sitten vastaavasti sen miten väriä käytetään.

04 Nov 17
Konvoluution kokeilu konvo.jar-ohjelman avulla Luento 18 – 9m42s (2m56s)
# vB13
Katso video: Konvoluutio Luento 18 2015 – 53m59s (3m37s)
# konvoluutio

Kopioi täydentämäsi Muunna-aliohjelma tähän.

 

B4. Taulukon sotkeminen

M: Satunnaisluvut. Etsi algoritmi kokonaislukutaulukon sekoittamiseksi ja toteuta algoritmi. Eli tee aliohjelma, joka ottaa vastaan int-taulukon ja sekoittaa TÄMÄN taulukon. Testaa algoritmiasi Console-sovellukset taulukolla, johon on esimerkiksi alustettu järjestyksessä luvut 1, 2, 3, ..., 52. Palauta toimiva ohjelmakooditiedosto, jossa on hyvin kommentoituna, mitä algoritmissa tehdään. Huom: Tässä ei ole tarkoitus "keksiä" omaa algoritmia, vaan käyttää ideaa jostakin valmiista algoritmista sekoittamiseen. Hyvä algoritmi on esim: Fisher-Yates shuffle. Tästä on toteutus Jypelin RandomGen -luokan Shuffle-aliohjelmassa. Voit matkia esimerkiksi tätä. Jos matkit tätä, niin vaihda T:n tilalle int ja listan tilalle int-taulukko. Aliohjelman alkuun pitää lisätä nyt Random rand = new Random(); jotta rand-olio on olemassa, Jypelin esimerkissä se on olemassa koska se on RandomGen-luokan attribuutti.

# random
Kirjoita ohjelma tähän.

 

Mitä tarkoittaa virhe "A namespace cannot directly contain members such as fields or methods"?

VL: tässä tapauksesa sitä että luokka puuttuu. Yleisesti sitä, että namespace-sanan jälkeen on jotakin muuta kuin luokka seuraavana. Meillä kun namespacea ei juurikaan ole käytetty, niin silloin se tarkoittaa että luokan ulkopuolelle on laitettu jotakin.

03 Nov 17 (edited 04 Nov 17)

G1-2. Lukujen esiintymät

Tee ohjelma, joka saa jostakin taulukon (tai käyttää vakiotaulukkoa), jossa on kokonaislukuja. Taulukossa sama luku voi esiintyä useasti. Kirjoita aliohjelma, joka saa tuon taulukon parametrinaan ja palauttaa taulukon, jossa on taulukon alkiot kukin vain yhden kerran järjestettynä niiden esiintymiskertojen määrän mukaan nousevaan järjestykseen. Taulukosta {1, 2, 3, 34, 34, 2, 1, 34, 1, 1, 1} palautetaan {3, 2, 34, 1}.

# guru
Kirjoita ohjelma tähän.

 

Esimerkki Haskell-kielellä tehtynä.

Pahasti pihalla

PP1

Tee ohjelma, jossa a) arvot kokonaislukuja listaan ja b) etsit halutun luvun esiintymien lukumäärän listassa. Aloita tekemällä aliohjelma, joka palauttaa halutun kokoisen listan arvottuja kokonaislukuja eli luo ensin listan, arpoo siihen tietyn määrän kokonaislukuja ja palauttaa lopuksi valmiin listan. Tämän jälkeen tee toinen aliohjelma, jonne viet parametreina käytettävän listan ja etsittävän alkion. Aliohjelma etsii (ja laskee), kuinka monta kertaa etsittävä alkio esiintyy listassa. Aliohjelma palauttaa löydettyjen alkioiden lukumäärän.

Vinkki: M:Dynaamiset tietorakenteet

# pp1

 

These are the current permissions for this document; please modify if needed. You can always modify these permissions from the manage page.