{"id":586,"date":"2018-11-30T00:34:54","date_gmt":"2018-11-29T22:34:54","guid":{"rendered":"https:\/\/coursepages.uta.fi\/tiep5\/?page_id=586"},"modified":"2019-01-25T16:20:32","modified_gmt":"2019-01-25T14:20:32","slug":"harjoitustyo2","status":"publish","type":"page","link":"https:\/\/coursepages2.tuni.fi\/tiep5\/syksy-2018\/harjoitustyot\/harjoitustyo2\/","title":{"rendered":"Harjoitusty\u00f6 2"},"content":{"rendered":"<h2>Teht\u00e4v\u00e4nanto ja muuta materiaalia<\/h2>\n<ul>\n<li><a href=\"http:\/\/www.sis.uta.fi\/~laki2\/syksy-2018\/harjoitustyot\/harjoitustyo2\/laki2_2018_harjoitustyo2.pdf\">Teht\u00e4v\u00e4nanto<\/a> pdf-muodossa.<\/li>\n<\/ul>\n<h2>Esimerkkitiedostot<\/h2>\n<p>Oman ohjelman tulosteita kannattaa vertailla esimerkkitiedostoihin ennen WETO-palautuksia.<\/p>\n<p>Jokaiseen esimerkkiin, <em>error<\/em>-esimerkki pois lukien, liittyy nelj\u00e4 tiedostoa. Ohjelmalle komentoriviparametrina annettava kuvatiedosto on <em>file<\/em>-alkuisessa tiedostossa. <em>Input<\/em>-alkuisessa tiedostossa ovat ohjelmalle annettavat komennot ja vastaavassa <em>output<\/em>-alkuisessa tiedostossa ovat komentoja vastaavat n\u00e4ytt\u00f6tulosteet. Sy\u00f6tteet ja niit\u00e4 vastaavat tulosteet on yhdistetty <em>combination<\/em>-alkuiseen tiedostoon.<\/p>\n<p><em>Error<\/em>-esimerkille ei ole annettu kuvatiedostoa, koska testiss\u00e4 annetaan virheellinen komentoriviparametri.<\/p>\n<p>Esimerkiksi <em>input_tree.txt<\/em>-tiedoston komennot tuottavat <em>output_tree.txt<\/em>-tiedoston sis\u00e4lt\u00e4m\u00e4t tulosteet, kun ohjelmalle annetaan komentoriviparametrina <em>file_tree.txt<\/em>-tiedosto. <em>Input_tree.txt<\/em>&#8211; ja <em>output_tree.txt<\/em>-tiedostojen sis\u00e4lt\u00f6 esitet\u00e4\u00e4n <em>combination_tree.txt<\/em>-tiedostossa yhdess\u00e4 aivan kuin komennot olisi annettu komentoikkunassa. <em>File<\/em>-esimerkin voi ajaa omalla ohjelmalla seuraavasti:<\/p>\n<p><code>java LakiHT2 file_tree.txt &lt; input_tree.txt &gt; out.txt<\/code><\/p>\n<p>Yll\u00e4 ohjelman tuloste kaapataan out.<em>txt<\/em>-tiedostoon uudelleenohjausmerkin &gt; avulla.<\/p>\n<p>Esimerkit ovat saatavilla kahdessa muodossa:<\/p>\n<ul>\n<li>Windows-muotoiset rivinvaihdot. N\u00e4m\u00e4 tiedostot ovat saatavilla <a href=\"http:\/\/www.sis.uta.fi\/~laki2\/syksy-2018\/harjoitustyot\/harjoitustyo2\/esimerkit\/\">yksitt\u00e4in<\/a> tai <a href=\"http:\/\/www.sis.uta.fi\/~laki2\/syksy-2018\/harjoitustyot\/harjoitustyo2\/esimerkit\/laki2_2018_harjoitustyo2_esimerkit.zip\">zip-paketissa<\/a>.<\/li>\n<\/ul>\n<ul>\n<li>Linux\/Mac-muotoiset rivinvaihdot. Saatavilla <a href=\"http:\/\/www.sis.uta.fi\/~laki2\/syksy-2018\/harjoitustyot\/harjoitustyo2\/esimerkit_lf\/\">yksitt\u00e4in<\/a> tai <a href=\"http:\/\/www.sis.uta.fi\/~laki2\/syksy-2018\/harjoitustyot\/harjoitustyo2\/esimerkit_lf\/laki2_2018_harjoitustyo2_esimerkit_lf.zip\">zip-paketissa<\/a>.<\/li>\n<\/ul>\n<p>Esimerkeist\u00e4 ei ole versioita eri merkist\u00f6ille, koska tiedostoissa on vain 7-bittisen ASCII-merkist\u00f6n &#8221;n\u00e4kyvi\u00e4&#8221; merkkej\u00e4, joiden esitystapa on sama niin Latin 1 (ISO 8859-1) kuin UTF-8-koodatussa Unicode-merkist\u00f6iss\u00e4.<\/p>\n<h2><span style=\"background-color: #ffff99\"><a name=\"salaiset\"><\/a>Salaiset testit<\/span><\/h2>\n<p>Salaiset testit ovat julkisessa testauksessa k\u00e4ytettyjen esimerkkien tapaan saatavilla kahdessa muodossa:<\/p>\n<ul>\n<li>Windows-muotoiset rivinvaihdot. N\u00e4m\u00e4 tiedostot ovat saatavilla <a href=\"http:\/\/www.sis.uta.fi\/~laki2\/syksy-2018\/harjoitustyot\/harjoitustyo2\/salaiset\/\">yksitt\u00e4in<\/a> tai <a href=\"http:\/\/www.sis.uta.fi\/~laki2\/syksy-2018\/harjoitustyot\/harjoitustyo2\/salaiset\/laki2_2018_harjoitustyo2_salaiset.zip\">ZIP-paketissa<\/a>.<\/li>\n<\/ul>\n<ul>\n<li>Linux\/Mac-muotoiset rivinvaihdot. Saatavilla <a href=\"http:\/\/www.sis.uta.fi\/~laki2\/syksy-2018\/harjoitustyot\/harjoitustyo2\/salaiset_lf\/\">yksitt\u00e4in<\/a> ja <a href=\"http:\/\/www.sis.uta.fi\/~laki2\/syksy-2018\/harjoitustyot\/harjoitustyo2\/salaiset_lf\/laki2_2018_harjoitustyo2_salaiset_lf.zip\">ZIP-paketissa<\/a>.<\/li>\n<\/ul>\n<h2>Kysymyksi\u00e4 ja vastauksia<\/h2>\n<p><strong>1. Mist\u00e4 aloittaisin?<\/strong><\/p>\n<p>Kokoa ohjelmaasi harjoitusty\u00f6h\u00f6n liittyvien harjoitusteht\u00e4vien ratkaisut. Harjoitusty\u00f6n teht\u00e4v\u00e4nannossa on mainittu joitakin hy\u00f6dyllisi\u00e4 teht\u00e4vi\u00e4. Kuudennen harjoituskerran ensimm\u00e4inen teht\u00e4v\u00e4 on erityisen hy\u00f6dyllinen, koska siin\u00e4 tehdyll\u00e4 operaatiolla saa ohjelmassa k\u00e4ytt\u00f6\u00f6n tekstitiedostoon tallennetun kuvan. My\u00f6s toinen ja kolmas teht\u00e4v\u00e4 liittyv\u00e4t suoraan harjoitusty\u00f6h\u00f6n. Tee main-operaatioon p\u00e4\u00e4silmukka, jossa kutsut jo harjoitusten yhteydess\u00e4 tehtyj\u00e4 operaatioita.<\/p>\n<p><strong>2. Voinko kutsua omaa operaatiota toisesta omasta operaatiosta?<\/strong><\/p>\n<p>Kyll\u00e4. Kaikkien omien operaatiokutsujen ei tarvitse l\u00e4hte\u00e4 main-operaatiosta. Oman operaation kutsuminen toisesta omasta operaatiosta on mahdollista ja t\u00e4ysin sallittua, kunhan kutsuketju ei veny liian pitk\u00e4ksi. Esimerkiksi nelj\u00e4 per\u00e4kk\u00e4ist\u00e4 operaatiokutsua on viel\u00e4 helposti ihmisen hahmotettavissa. Usein on j\u00e4rkevint\u00e4 kutsua tiettyyn operaatioon liittyv\u00e4\u00e4 apuoperaatioita suoraan kyseisest\u00e4 operaatiosta.<\/p>\n<p><strong>3. Miksi latausoperaationi kaatuu, vaikka koodi on kunnossa?<\/strong><\/p>\n<p>Tarkista, ett\u00e4 k\u00e4ytt\u00e4m\u00e4si testikuvan rivit ovat samanpituisia ja ett\u00e4 my\u00f6s viimeisell\u00e4 rivill\u00e4 on rivinvaihto.<\/p>\n<p><strong>4. Miten saan selville mill\u00e4 rivill\u00e4 try-catch-lausetta k\u00e4ytt\u00e4v\u00e4 operaatio kaatuu?<\/strong><\/p>\n<p>Voit haarukoita kaatumiskohdan paikan seuraamalla ohjelman etenemisist\u00e4 tulostuslauseilla. On kuitenkin helpompaa kutsua catch-kohdassa printStackTrace-operaatiota parametrina saadun poikkeuksen kautta. Operaatio tulostaa n\u00e4yt\u00f6lle samanlaisen &#8221;poikkeuspinon&#8221; kuin Java-tulkki ohjelman kaatuessa.<\/p>\n<p>Esimerkiksi:<\/p>\n<pre>\/\/ Siepataan mik\u00e4 tahansa poikkeus.\r\n<strong>catch<\/strong> (Exception e) {\r\n   e.printStackTrace();\r\n\u00a0\u00a0 merkit = <strong>null<\/strong>;\r\n}<\/pre>\n<p><strong>5. Kuinka tunnistaa parametrillinen suodatuskomento?<\/strong><\/p>\n<p>Esimerkiksi muotoa &#8221;filter 5&#8221; olevan komennon voi tunnistaa String-luokan startsWith-operaatiolla antamalla parametrin arvoksi &#8221;filter&#8221; tai mieluummin &#8221;filter&#8221;-arvoisen vakion.<\/p>\n<p><strong>6. Onko kuvatiedosto merkki- vai lukumuodossa?<\/strong><\/p>\n<p>Kuvat ovat merkkein\u00e4 (katso teht\u00e4v\u00e4nannon toinen kuva). Teht\u00e4v\u00e4nannon leip\u00e4tekstiin oli j\u00e4\u00e4nyt kahteen kohtaan maininta kuvan lukuesityksest\u00e4 tiedostossa, mist\u00e4 pahoittelut.<\/p>\n<p><strong>7. Kuinka lasken reunan leveyden?<\/strong><\/p>\n<p>Reunan leveyden ja samalla mitan suodinikkunan keskipaikasta ikkunan reunalle saa jakamalla suodinikkunan sivun pituuden (<strong>int<\/strong>) kahdella, jolloin Java h\u00e4vitt\u00e4\u00e4 tarpeettomat desimaalit. Esimerkiksi:<\/p>\n<pre><strong>int<\/strong> reunanLeveys = suotimenSivunPituus \/ 2;<\/pre>\n<p>Jos yll\u00e4 suodin on esimerkiksi 3 x 3 -kokoinen, saadaan reunan leveydeksi 3 \/ 2 = 1 Javan laskus\u00e4\u00e4nn\u00f6ill\u00e4.<\/p>\n<p><strong>8. Miksi en voi kopioida taulukkoa sijoittamalla?<\/strong><\/p>\n<p>Suodatuksessa tarvitaan uusi lukutaulukko (tuloskuva), jonka reunoilla on samat arvot kuin vanhassa lukutaulukossa (l\u00e4ht\u00f6kuva). Taulukon sis\u00e4ll\u00f6n kopiointi toiseen taulukkoon ei onnistu t\u00e4h\u00e4n tapaan:<\/p>\n<pre><strong>int<\/strong> rivlkm = vanhatLuvut.length;<strong>\r\nint<\/strong> sarlkm = vanhatLuvut[0].length;<strong>\r\nint<\/strong>[][] uudetLuvut = <strong>new int<\/strong>[rivlkm][sarlkm];<strong>\r\n...\r\n<\/strong>uudetLuvut = vanhatLuvut;<\/pre>\n<p>koska taulukkomuuttujia (viitteit\u00e4) sijoitettaessa vasemmanpuoleinen operandi liitet\u00e4\u00e4n samaan taulukkoon (olioon) kuin oikeanpuoleinen operandi. Sijoituksen lopputuloksena yhteen taulukkoon (olioon) liittyy kaksi muuttujaa (viitett\u00e4), jolloin suodatuksessa k\u00e4ytet\u00e4\u00e4n aiemmin suodatettuja arvoja ja ohjelma vaikuttaa toimivan omituisesti ilman n\u00e4kyv\u00e4\u00e4 syyt\u00e4.<\/p>\n<p>Tee taulukon kopiointiin erillinen apuoperaatio, jossa taulukon merkit kopioidaan toiseen taulukkoon. Esimerkki operaation kutsusta:<\/p>\n<pre><strong>int<\/strong> rivlkm = vanhatLuvut.length;<strong>\r\nint <\/strong>sarlkm = vanhatLuvut[0].length;<strong>\r\nint<\/strong>[][]uudetLuvut = <strong>new int<\/strong>[rivlkm][sarlkm];<strong>\r\n...\r\nboolean<\/strong> onnistui = kopioiTaulukko(vanhatLuvut, uudetLuvut);<\/pre>\n<p>Operaation voi toteuttaa my\u00f6s siten, ett\u00e4 se luo kohdetaulukon itse, kopioi merkit parametrina saamastaan taulukosta kohdetaulukkoon ja palauttaa viitteen uuteen taulukkoon. Esimerkki operaation kutsusta:<\/p>\n<pre><strong>char<\/strong>[][] uudetLuvut = kopioiTaulukko(vanhatLuvut);<\/pre>\n<p>Kopiointia voi tehostaa molemmissa tapauksissa kopioimalla vain reuna-alkiot. T\u00e4ll\u00f6in reunan leveys t\u00e4ytyy v\u00e4litt\u00e4\u00e4 operaatiolle parametrina.<\/p>\n<p><strong>9. Miten j\u00e4rjest\u00e4\u00e4 operaatiot?<\/strong><\/p>\n<p>Sijoita main-operaatio joko ohjelman alkuun tai loppuun. Muiden operaatioiden osalta voisi suositella, ett\u00e4 yhteenkuuluvat operaatiot ovat l\u00e4hell\u00e4 toisiaan, jotta koodia olisi helpompi lukea. Koodia voi ryhmitell\u00e4 my\u00f6s pieniin apuoperaatioihin ja t\u00e4rke\u00e4mpiin operaatioihin ja j\u00e4rjest\u00e4\u00e4 yhteenkuuluvat operaatiot l\u00e4helle toisiaan n\u00e4iden kahden ryhm\u00e4n sis\u00e4ll\u00e4. Muitakin vaihtoehtoja toki on.<\/p>\n<p><strong>10. Ideoita suodatuksen toteuttamiseen?<\/strong><\/p>\n<p>Suodatukseen tarvitaan nelinkertainen silmukka. Ensimm\u00e4inen silmukkapari k\u00e4y l\u00e4pi kaikki l\u00e4ht\u00f6kuvan alkiot paikoissa (<em>i<\/em>, <em>j<\/em>) , joihin voidaan asettaa suodinikkunan siten, ett\u00e4 ikkunan keskipiste on paikassa (<em>i<\/em>, <em>j<\/em>) ilman, ett\u00e4 suodinikkuna menee kuvan ulkopuolelle. Silmukoiden rajoja (alkuarvo ja yl\u00e4raja) asetettaessa on huomioitava reunan leveys (7. kysymys).<\/p>\n<p>Toinen silmukkapari laskee yhteen suodinikkunan &#8221;alla&#8221; olevien alkioiden arvot. T\u00e4m\u00e4nkin silmukkaparin rajojen muotoilussa on hy\u00f6ty\u00e4 reunan leveyden tuntemisesta. Toinen silmukkapari kannattaa erist\u00e4\u00e4 selkeyden vuoksi omaan operaatioon, jolle v\u00e4litet\u00e4\u00e4n varsinaisesta suodattavasta operaatiosta parametrina l\u00e4ht\u00f6kuva, ulomman silmukkaparin m\u00e4\u00e4r\u00e4\u00e4m\u00e4 paikka (<em>i<\/em>, <em>j<\/em>) ja reunan leveys. Operaatio palauttaa joko alkioiden summan tai suoraan keskiarvon.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Teht\u00e4v\u00e4nanto ja muuta materiaalia Teht\u00e4v\u00e4nanto pdf-muodossa. Esimerkkitiedostot Oman ohjelman tulosteita kannattaa vertailla esimerkkitiedostoihin ennen WETO-palautuksia. Jokaiseen esimerkkiin, error-esimerkki pois lukien, liittyy nelj\u00e4 tiedostoa. Ohjelmalle komentoriviparametrina annettava kuvatiedosto on file-alkuisessa tiedostossa. Input-alkuisessa tiedostossa ovat ohjelmalle annettavat komennot ja vastaavassa output-alkuisessa tiedostossa ovat komentoja vastaavat n\u00e4ytt\u00f6tulosteet. Sy\u00f6tteet ja niit\u00e4 vastaavat tulosteet on yhdistetty combination-alkuiseen tiedostoon. Error-esimerkille ei &hellip; <a href=\"https:\/\/coursepages2.tuni.fi\/tiep5\/syksy-2018\/harjoitustyot\/harjoitustyo2\/\" class=\"more-link\">Jatka artikkeliin <span class=\"screen-reader-text\">Harjoitusty\u00f6 2<\/span><\/a><\/p>\n","protected":false},"author":6,"featured_media":0,"parent":396,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-586","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/coursepages2.tuni.fi\/tiep5\/wp-json\/wp\/v2\/pages\/586","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coursepages2.tuni.fi\/tiep5\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/coursepages2.tuni.fi\/tiep5\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/coursepages2.tuni.fi\/tiep5\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/coursepages2.tuni.fi\/tiep5\/wp-json\/wp\/v2\/comments?post=586"}],"version-history":[{"count":26,"href":"https:\/\/coursepages2.tuni.fi\/tiep5\/wp-json\/wp\/v2\/pages\/586\/revisions"}],"predecessor-version":[{"id":708,"href":"https:\/\/coursepages2.tuni.fi\/tiep5\/wp-json\/wp\/v2\/pages\/586\/revisions\/708"}],"up":[{"embeddable":true,"href":"https:\/\/coursepages2.tuni.fi\/tiep5\/wp-json\/wp\/v2\/pages\/396"}],"wp:attachment":[{"href":"https:\/\/coursepages2.tuni.fi\/tiep5\/wp-json\/wp\/v2\/media?parent=586"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}