Tehtävä 3 – Kuva

Kolmannnen kierroksen tehtävän tavoitteena oli ohjelmoida kourallinen suotimia joilla kuvia voisi muokata. Itse käyttöliittymä oli annettu valmiiksi, mutta molemmat suodintyypit (PixelFilter ja FourierFilter) piti viimeistellä itse annetun rungon päälle. Tässä tehtävässä hyödynnettiin ensimmäistä kertaa abstrakteja luokkia; näin kumpaakin suodintyyppiä voitiin käyttää samalla tavalla, vaikka niiden sisäinen toteutus olikin aivan erilainen.

Auringonkukka

Kohdekuvamme

PixelFilter muokkasi kuvia annetun matriisin perusteella. Tämä oli varsin mielenkiintoista, sillä oikeasti selvisi “miten matriisilla kerrotaan pikseleitä” ja myös miten monia tuttuja suotimia voi ylipäätään toteuttaa! Todennäköisesti moniin suotimiin on kuitenkin monia eri tapoja, varmasti tehokkaampiakin, mutta tässä pääsi hyvin alkuun. Alla on esimerkkejä muutamista eri efekteistä, osa poimittu GIMPin ohjemateriaalista matriiseja koskien.

PixelFilter-suotimia

Vasemmalta oikealle: sumennus (blur), tarkennus (sharpen), reunanlöytö (edge detect) ja kohokuva (emboss)

Itse vedin PixelFilterin toteutuksen vähän överiksi ja tein oman MatrixFilter -luokan, joka sisälsi kaiken tarvittavan tiedon matriisista: sen nimen, itse matriisin, loppukertoimen, kohdekanavien (R, G, B) ja totuusarvon määrittämään kummassa väriavaruudessa kuvaa suodittiin – RGB:ssä vai HSV:ssä. Lopputuloksena ei tarvinnut kuin lisätä uusi instanssi listaan ja rivi pixelfilter.txt:hen niin operateFilter teki taikansa ilman muuta säätöä. Lisäksi kiersin tehtävänannossa mainitun reunaongelman teeskentelemällä kuvan jatkuvan samana reunojen yli.

FFT

Puolitiehen jätetty kuva, joka on käynyt kerran FFT:n läpi ja saanut reunojensiirron

FourierFilter muokkasi kuvia taajuusavaruudessa, ja se oli aivan yhtä selkeä asia kuin miltä kuullostaakin. Onneksi FFT-muunnoksia ei tarvinnut itse keksiä, vaan ohjeita orjallisesti noudattaen lopuksi voi huomata koodin toimivankin vaikka teoria menisikin ohitse. Yllä oleva kuva ei tietenkään ole riittävä alkuperäisen auringonkukan muodostamiseen, sillä FastFourierTransformin jälkeen kuva on jaettu kahteen osaan: reaali- sekä imaginääriosaan. FourierFilter käytännössä kertoo FFTn jälkeisiä arvoja (reaali ja imaginääri) ja sitten muuntaa kuvan takaisin ymmärrettävään muotoon.

Esimerkkejä taajuusavaruuden suotimista:

Notch

Notch

Lowpass

Lowpass

Highpass

Highpass

Ring

Ring

Bonus! Aaltokuvio joka syntyi kirjoitusvirheen ansiosta. Maskia ei voi näyttää, sillä se ylitti reaalimaailman rajat.

Waves

Waves

Tehtävässä oli myös ongelma ratkottavana: kuinka puhdistaa “vahingoittunutta” kuvaa taajuusavaruuden avuin.

Image

Virheellinen kuva taajuusaravuutensa kanssa.

Itse sain jotain aikaan poistamalla pikselirykelmiä, jotka selkeästi poikkesivat alkuperäisestä kuvasta.

Korjailtu kuva

Korjailtu kuva

Kun tehtävän haastavuudesta selvisi, oli se yllättävän hauska; kuvia sai muokattua ihan itse monilla eri tavoin ja tulevaisuudessa muistan kyllä miten matriisifiltterit toimivat.

Advertisements

Tehtävä 2 – Koodaus ja dekoodaus

Kakkoskierroksella tehtävänä oli toteuttaa metodeita, joiden avulla voidaan luoda bittijonolle toistokoodaus, tai dekoodata tälläinen bittijono. Piti myös toteuttaa metodit, joiden avulla pystytään luomaan virheitä erinäisillä parametreillä mallintamalla, sekä selvittää tuntemattoman bittijonon sisältö.

Ensivaikutelma tehtävästä oli erittäin positiivinen! Kunnolla koodaamista, erittäin mielenkiintoinen aihe, kohtuullisen vapaat kädet silti ohjeistuksen ollessa selkeää.. Mitä muuta olisi voinut haluta? Ylimääräistä aikaa kenties, mutta tehtävä oli itsessään todella hauska toteuttaa. Etenkin digitaaliarkeologia antoi mukavaa haastetta, ja oli varsin hauska osa tätä kierrosta. Veikkaan kuitenkin, että ohjelmoinnin aloittelijoille tehtävä varmasti aiheutti enemmän kuin tarpeeksi ongelmia, jos siinä oli hieman mietittävää jo kokeneemmallekin koodarille.

Muistelisin, että kuvan käsitteleminen virheillä ja virheistä selviytymisen tutkiminen käytännön kautta oli varsin hauskaa. Scalan syntaksi tuli huomattavasti tutummaksi ja “bittijonojen” käsittely on aina hyvää harjoittelua. Tehtävä myös laittoi miettimään tehokkaampia ratkaisuja ja hieman kiinnostumaan siitä, miksi tämmöisiä ongelmia kohdataan ja kuinka olennaista niihin varautuminen on. Kaiken kaikkiaan tämä oli todella hauska, vaikkakin hieman työläs tehtävä.

– Esa Koskinen

Tehtävä 0 – Tieto tietokoneessa

Ensimmäisellä kierroksella oli tehtävänä luoda käsitekartta siitä, miten tiedon tallentaminen ja esittäminen toteutetaan tietokoneessa. Muistan tätä kierrosta erityisellä lämmöllä </3 Yliopisto-opinnot olivat vielä omalta osaltani alkuvaiheessa – ja niin varmasti monella muullakin kurssin kävijöistä – ja tälläinen laajempi tehtävä vaikutti suunnattomalta. Mielestäni tehtävänanto oli aivan liian avoin sekä turhan abstrakti, ja muutenkin monella oli ensimmäisten olosessioiden jälkeen varsin negatiivisia odotuksia harjoitustehtävien tekemisestä. Muutenkin luulen, että käsitekartta oli käsitteenä monelle uusi, joka entisestään lisäsi tuskailua.

Näin jälkikäteen ajateltuna, ei kyseessä ole oikeastaan hirveän valtava tehtävä, etenkään nyt kun on tarkempi käsitys kurssin arvosteluperiaatteista. Alkupäässä otin kuitenkin valtavat paineet niin deadlinestä kuin ohjeistuksen epämääräisyydestäkin. Aloittaminen tuntui raskaalta, ja se tuli tehtyä liian myöhään – sain tuntien tuskailun lopputuloksena vain varsin kehnon ja epäselkeän paperilla tehdyn kuvauksen aiheesta. Ei hyvä.

Tein sitten tehtävän uudestaan, tällä kertaa käyttäen suositeltuja ConseptMap Toolseja, suunnittelin rakenteen tarkemmin jo alkuvaiheessa ja paneuduin sen tekoon oikeasti ajatuksella muutamien tuntien ajan. Tällä kertaa käsitekarttani oli jo huomattavasti informatiivisempi sekä viimeistellyn oloinen. (sitä ei ole vielä arvosteltu, tosin; töks töks)

Luulen, että hieman toisenlainen tai pienempiin osakokonaisuuksiin jaoiteltu tehtävä olisi kenties sopinut tähän vaiheeseen kurssia paremmin. Olen varma, että ensimmäisten kahden kierrosten tehtävistä on tullut paljon itkua suunnasta jos toisestakin.. Tämän tyyliset tehtävät eivät oikein iske. Näin jälkeenpäin ajatellen käsitekartan teko oli kuitenkin tarpeeksi mielenkiintoista ja opin siitä kohtuullisesti – vaikkei se siltä aluksi tuntunutkaan.

– Esa Koskinen

Tehtävä 6 – Pienpelit

Viimeisessä harjoitustyössä saimme tehtäväksemme kirjoittaa Scalalla ohjelman, jossa olisi mahdollista päästä pelaamaan kolmea klassista pienpeliä (eng. minigame): ristinollaa, hirsipuuta sekä ping pongia (jota kutsutaan myös pöytätennikseksi). Tehtävään ei meille annettu valmista ohjelmakoodin runkoa, eli meidän tuli kirjoittaa ohjelma itse alusta alkaen. Itselleni tämä oli varsin posiitiivinen seikka, sillä aiemmilla kierroksilla olen ollut vähän ongelmissa nimenomaan valmiiksi annettujen koodinpätkien kanssa.

Kun ensimmäisen pelin kohdalla olin edennyt jonkin matkaa, oli varsin selkeästi huomattavissa, että syksyn aikana kurssien tarjoama “ohjelmointityyli-propaganda” oli tehnyt tehtävästä varsin tehokkasti. Ohjelman eri osien jaoittelu ohjelmakoodiin, kun näytti kumman tutulta verrattuna kursseilla nähtyihin valmiisiin koodinpätkiin.

Suurin uudistus aiempiin tehtäviin nähden oli nyt siis se, siinä missä aiemmin on pitänyt vain toteuttaa yksittäisiä palsia suuremmasta ohjelmakokonaisuudesta, niin nyt piti itse myös suunnitella ohjelman rakenne ja pitää huoli siitä, että lopullisessa ohjelmakoodissa olisi oma paikkaansa ohjelman jokaiselle palaselle.

Suurimman haasteen tehtävässä ainakin itselleni muodosti swing-grafiikkakirjasto. Eritysesti se, että sai ikkunan elementtien asettelun kuntoon tuotti hankaluuksia. Myös paintComponent metodin ylikirjoituksesta näytti seuraavan varsin outoja asioita, jotka toisaalta ymmärrän, mutta taas toisaalta, “miksi ihmeessä asia pitää tehdä oikesti tehdä näin vaikeaksi”  kun monet muutkin ohjelmointikielet ja kirjastot ovat siinä onnistuneet. Ilmeisesti joitakin vaihtoehtoja swing/awt yhdistelmälle olisi tarjolla, mutta täydellinen tiedonpuute asiaan liityen ei juuri houkuttanut siihen, että olisi kokonaan uuden kirjaston käyttöä alkanut opettelimaan.

Tehtävän kaksi pääpainopistettä olivat siis mielestäni ehdottomasti oman ohjelman rakenteen suunnittelu, sekä grafiikkakirjastoihin tutustuminen. Itse pelilogiikoista vaikeuksia tuotti lähinnä vain pingpong -pelin törmäyksien käsittely. Muilla opiskelijoilla tilanne oli ilmeisesti ollut aika samankaltainen, eli vaikeudet olivat lähinnä painottuneet pingpong -pelin logiikoihin.

Toivottavasti kovin monella opiskelijalla tunnelmat eivät kuitenkaan ollet samat, kuin tällä hirsipuussa epäonnistuneella ukkelilla:

ukko

alkuperäinen kuva: http://www.republicofcode.com/tutorials/flash/hangman/

Antti Virtanen

Tehtävä 4 – Web teknologiat

Tässä harjoitustyössä tehtävänä oli kirjoittaa essee web-teknologioista. Aiempien kirjallisten tehtävien tapaan oli tehtävän anto tälläkin kertaa varsin väliä, joten esseen työstäminen oli käytännössä pakko aloittaa aiheen jonkinlaisella rajaamisella. Lähinnä piti siis päättää kuinka laajasti ja miltä osin käsittelisi mitäkin web-teknilogioiden osa-aluetta. Kaikkia osa-alueita kun tovottiin käsiteltävän jollakin tasolla.

Itse päädyin jakamaan aiheen kolmeen osaan: yhteyteen, palvelimeen ja selaimeen. “Nörttikielellä” siis frontend, backend ja mitä siinä välillä tapahtuu. Yhteyttä käsittelin vain lyhyesti. Lähinnä siiltä kannalta, miten palvelin ja selain kummunikoivat keskenään HTTP- , eli nettisivu-liikenteessä ylimällä ja sille tyypillisimmällä tasolla. Tähän kummunikaatioon kun tavallinen kotikoneen käyttäjäkin voi törmätä varsin usein mm. 404-error viestin muodossa.

Toisesta osa-alueesta, palvelimesta kirjottaessani törmäsin ensimmäisen kerran aiheeseen liittyvään käsitetulvaan. Erilaisia käsitteitä (teknologioita, tuotenimiä yms.) kun on valtavasti. Näistä kun jotkin tarkoittavat samaa asiaa, jotkin melkein samaa asiaa ja joitakin käytetään joissakin yhteyksissä väärin, niin yritä siinä sitten päästä selville siitä mikä on se paras käsite juuri tähän kyseiseen kohtaan omaa tekstiäsi. Pääasiassa päädyin käyttämään eri tuotenimiä, sillä niitten määrittely kun on usein varsin yksiselitteinen.

Palvelinmen käsittelyssä koin tärkeimmiksi osa-alueiksi erilaiset kääntäjän sekä tietokannat. Lähinnä koska koin ne suurimmiksi eroavaisuuksiksi selaipuolen teknologioihin nähden.

Selainteknologioiden käsittelyn tiivistin oikeastaan kolmeen käsitteeseen: html, css ja javascript, sekä siihen mikä kunkin tehtävä nettisivulla on. Näiden erilaisista yhdistelmistä (jQuery, Bootstrap jne.) olisi taas tietysti voinut tarinoida vaikka maailman tappiin asti, mutta päädyin pysyttelemään vain kolmessa käsitteessä itsessään.

Henkilökohtaisesti suurimmat oppimis-saavutuksen käpahtuvat varmaankin palvelin puolen käsitteiden tasolla. Muilta osin en näin laaja-alaisessa esseessä oikein päässyt oman vanhan tietämykseni ulkopuolelle. Ehkä tämän työn olennaisin anti myös muille opiskelijoille oli nimeen omaan aiheeseen liityvät käsitteet. Niiden ymmärtäminen kun helpottaa huomattavasti aiheen pariin palaamista tulevaisuudessa. Aika monilta ohjelmoinnin vasta aloittaneilta kun nimenomaan nämä käsitteet ovat hukassa ja sen vuoksi kulloikin aiheeseen liityvän tiedon löytäminen voi olla vaikeaa. Tästä näkökulmasta tehtävänannon jättäminen laaja-alaiseksi oli mielestä hyvä valinta.

 

Antti Virtanen

Tehtävä 1 – Luokat ja oliot

Toisen harjoitustehtävän tarkoituksena oli tutustuttaa opiskelijat UML-mallinnuksen perusteisiin. Tehtävänantona oli luoda luokkakaavio, joka kuvaa puhelinlaskuja hallitsevan järjestelmän toimintaa sekä kirjoittaa sen kylkeen pienimuotoinen essee. Tekstissä piti avata oman kaavion toimintaa ja kertoa yleisesti UML:n ominaisuuksista kuten esimerkiksi niistä käytännöistä, joilla kaavioissa merkataan luokkien välisiä yhteyksiä.

Tehtävää tehdessä monet olivat vielä opiskelun ja koodamisen suhteen aika alkutaipaleella, mikä aiheutti ainakin minulle (ja kuulemani mukaan muutamalle muullekin..) päänvaivaa. Tehtävä löi lievästi korville, koska tässä kohtaa joutui ensimmäistä kertaa opiskeluaikana tekemään astetta haastavamman ja työläämmän tehtävän. Olio-ohjelmointi ja yleiskäsitys ohjelmien rakenteista oli vielä vähän hakusessa ja asiaa ei helpottanut se, että tehtävänanto oli tarkoituksella melko avoin, minkä ansiosta olennaisen asian suodattaminen lopulliseen työhön jäi itselle mietittäväksi.

Tästä tehtävästä sai kuulla kovaa purnausta aika monen kanssaopiskelijan suusta ja se on helppo ymmärtää. Työ oli hämmentävä, työläs eikä kovinkaan mielenkiintoinen. Aihealue oli toisaalta ihan hyödyllinen, mutta tehtävän ajoitus meni mielestäni vähän pieleen. Ehkä jos sama homma olisi tarjottu yksi tai pari kuukautta myöhemmin, olisi työ tuntunut kevyemmeltä ja oppiminen olisi ollut vähän hedelmällisempää.

Se mitä työstä jäi itselle käteen, oli parempi käsitys olioiden välisestä toiminnasta. Lisäksi pääsi tutustumaan täysin uuteen asiaan eli UML-mallinnukseen. Täytyy kuitenkin todeta, että tehtävä ei ehkä tarjonnut ihan tarpeeksi vastinetta sille ajalle, minkä tähän joutui kuluttamaan.. ellei sitten tulevaisuudessa joudu enemmänkin tekemisiin UML:n kanssa?

— Karri Haranko

Tehtävä 5 – Tietokonegrafiikka ja vuorovaikutus (Sokoban)

Kurssin viidennen kierroksen harjoitustyön aiheena oli ohjelmoida yksinkertaistettu versio klassikoksi muodostuneesta Sokoban-ongelmanratkaisupelistä. Sokobanissa pelaaja siirtelee laatikoita tai muita vastaavia esteitä ennalta määrättyihin paikkoihin, ja pelin läpäistäkseen pelaajan on saatava siirrettyä kaikki laatikot merkityille paikoille. Pelin osatehtävien ratkaisemiseksi pelaajan täytyy aina miettiä, millaisia seurauksia tietyn esteen siirtämisellä on jatkoa ajatellen.

Scala-muotoinen ohjelmointitehtävämme oli tosiaankin karsittu versio alkuperäisestä esikuvastaan, sillä meidän versiossamme pelin osatehtävien läpäisemiseksi riitti ainoastaan esteiden siirteleminen pois kulkuväylältä siten, että pelaaja pääse maaliin. Tämän kertainen koodaustehtävä oli täysin erilainen kuin edellisen kierroksen kuvasuotimien kanssa puuhastelu. Kuvakoodauksen jäljiltä minulla, jolla ei ennen Otaniemeen ja Tikille tuloa ollut mitään aikaisempaa kokemusta ohjelmoinnista, oli varsin kaksijakoiset tuntemukset ohjelmoinnista. Toisaalta oli onnistunut fiilis, kun olin saanut aluksi ylipääsemättömän vaikealta tuntuneen tehtävän kunnialla tehtyä. Toisaalta oli vähän sekavat tuntemukset siitä, että tälläistako ohjelmointi sitten ylipäätänsä tulee olemaan, sekavaa ja raskasta. Onneksi tämän viidennen kierroksen Sokoban oli lähempänä sitä, mitä olin ehkä jonkin verran ohjelmoinnilta odottanutkin, vaikka sisältyyhän koodaamiseen paljon muutakin kuin graafisten käyttöliittymien parissa työskentelyä.

Tämän kertaisen näpyttelyn tehtävänanto oli jo mielestäni sitä tasoa, jota voisi ohjeistukselta odottaakin; selkeä ja kattava. Lisäksi kierrokseen liittyvän OLO-tapaamisen virike antoi perustietoa piirtämiseen tarkoitetun Graphics2D-luokan käytöstä, jota hyödynnettiin Sokobanin graafisen ilmeen muodostamisessa. Ohjelmointi 1 -kurssilla graafisia käyttöliittymiä oli jo aikaisemmin sivuutettu hiukan, mutta sen enemmin niistä tiedoista ei tässä tehtävässä ollut apua.  Näillä perusteilla ryhdyin tuottamaan tehtävän vaatimaa koodia ja aluksi tehtävä tuntuikin haastavalta,  mutta kun aiheesta sai kunnon otteen ja teki omaa etsivän työtä, alkoi koodia syntyä tasaiseen tahtiin. Tehtävän suorittamisen kannalta varmasti eniten haasteita tuotti siis se, että Scalan Swing-kirjaston oma dokumentaatio ei näin aloittelevan ohjelmoijan näkökulmasta ole se kaikkein selkein ja yksinkertaisin opas. Pulmien ratkaisemiseksi jouduinkin käyttämään huomattavan paljon Googlea apunani, jotta Eclipsen antamista virheviesteistä päästiin eroon. Assareiden antamaa apua ei pidä sitäkään yhtään vähätellä, sillä ilman heitä tämän kurssin suorittamisesta ei yksinkertaisesti tulisi yhtään mitään.  Tehtävä itsessään ei siis loppujen lopuksi ollut edes kovin vaikea, mutta ensikertalaisen alkuhaparoinnit tuottivat aluksi mutkia matkaan eikä tehtävänannon kuvan mukaiselta reaktioltakaan voitu välttyä, mutta onneksi virheet oli helposti löydettävissä ja korjattavissa. Suurimmat ongelmat johtuivatkin siis Swing-kirjaston dokumentaation auttamattomasta köyhyydestä, tai ehkä en vain osannut hyödyntää sen kaikkea potentiaalia.

Tehtävän palauttamisen jälkeen miettiessäni, mitä kierroksesta oli jäänyt käteen, pystyin rehellisesti toteamaan, että aika paljonkin. Opin nimittäin käyttämään Graphics2D:tä ja Scalan Swingiä perustasolla, ja näitähän tullaan hyödyntämään myös kurssin seuraavalla ja samalla myös kurssin päättävällä ohjelmointikierroksella, jossa koodataaan yhteensä kolme pientä peliä ja omien mieltymysten sekä taitojen mukaan myös lisäpelejä.

Tässä vielä lopuksi kuvakaappaus omasta tuotoksestani tältä harjoituskierrokselta. Aikaansaannokseni ei kuitenkaan ole se kaikkein kaunein monipuolisin toteutus, jonka tehtävänannon puitteissa olisi voinut koodata, mutta aikaa on aina rajallinen määrä ja haasteiden tuomat viivästykset syövät sitä yleensä yllättävän paljon. Nyt voin kuitenkin luottavaisin mielin jatkaa kohti finaalikierrosta. 🙂

Kierros 5 - Sokoban


Markus Pajari