Ohjelmoinnin peruskurssi Y2, kurssimateriaali

2.3. Tehtävä: Intervallit (190 p)

«  2.2. Pythonin poikkeukset   ::   Etusivulle   ::   3. Kierros 3 (7.2.2016 kello 23:59)  »

2.3. Tehtävä: Intervallit (190 p)

Tästä sivusta:

Mitä käsitellään? Luokkia, metodeja, poikkeuksia.

Mitä tehdään? Kirjoitetaan koodia joka hyödyntää perintää.

Suuntaa antava vaativuusarvio: Keskivaikea lähinnä uusien asioiden vuoksi. Itse tehtävä ei lopulta ole kovin haastava.

Suuntaa antava työläysarvio: 1-2 tuntia

Pistearvo: 190 pistettä

Intro

Tehtävässä muutetaan annettua luokkaa ja kirjoitetaan oma poikkeusluokka.

Tausta

Perehdymme Allenin intervallialgebraan, jonka avulla voidaan esittää tietoa tapahtumien ajallisista suhteista. Idea on, että kuhunkin tapahtumaan liittyy aikaväli (eli intervalli), jolla on alku- ja loppuhetket. Kun vertaamme kahteen tapahtumaan liittyviä tunnettuja aikavälejä a ja b voimme havaita 13 eri mahdollisuutta:

Suhde Käänteissuhde
a before b b after a
a meets b b met-by a
a overlaps b b overlapped-by a
a starts b b started-by a
a during b b contains a
a finishes b b finished-by a
a equal b b equal a

Suhteista löytyy siis kuusi suhdetta, joilla kullakin on käänteissuhde ja yksi suhde, joka on symmetrinen (equal). Esitetään suhteet vielä kuvana, josta havainnollistuu, miten aikavälit sijaitsevat suhteessa toisiinsa.

../../_images/allen-relations.png

Esimerkki

Tarkastellaan lauseita: Luennon aikana Pekka nukkui. Luennon jälkeen hän ruokaili. Tässä on kolme aikaväliä:

  • L: Pekka oli luennolla.
  • N: Pekka nukkui.
  • R: Pekka ruokaili.

Tietämättä intervallien alku- ja loppuaikoja voimme annettujen lauseiden perusteella päätellä (olettaen, että Pekka ei kävele unissaan ja hän ei nukkunut luentosalissa jo, kun luento alkoi), että:

  • N starts L (nukkui heti luennon alussa, mutta ei koko luentoa)
    or N during L (nukkui kesken luennon, mutta ei alussa eikä lopussa)
    or N finishes L (nukkui luennon lopussa, mutta ei koko luentoa)
    or N equal L (nukkui koko luennon)
  • L before R or L meets R

(On toki mahdollista, että Pekan nukkuminen koostui useammasta aikavälistä, jotka voisivat olla suhteissa starts, during tai finishes luentoon).

Tässä tehtävässä käsittelemme intervalleja, mutta aloitamme intervalleilla, joiden alku- ja loppuhetket ovat tiedossa.

Tehtävä

Annetut tiedostot

Saat valmiina koodina tiedostot interval_interface.py sekä allen_relation.py.

Palautettava tiedosto

Palauta koodisi tiedostossa nimeltä interval.py.

Mitä pitää tehdä?

  • Tee tiedostoosi interval.py poikkeusluokka IntervalError, joka esittää intervallien käsittelyssä havaittua poikkeustilannetta. Valitse sopiva Pythonin valmis poikkeusluokka yläluokaksi.
  • Tee tiedostoosi interval.py luokka Interval, joka on valmiina tarjotun luokan IntervalInterface alaluokka. Kyseinen luokka määrittää ainoastaan intervallioperaatioiden otsikot, mutta ei mitään toteutusta niille.
  • Tee luokkaan alustusmetodi __init__, joka tallettaa alku- ja loppupisteet. Lisäksi metodisi tulee tarkistaa, että loppupiste ei ole pienempi kuin alkupiste ja nostaa poikkeuksen, mikäli näin ei ole. Laita poikkeukseen parametrina jokin viesti.
  • Luokassa IntervalInterface määritetään intervallipredikaatit (before, meets jne.), mutta ei mitään toteutuksia niille. Toteuta nämä alaluokassasi Interval. Katso yllä olevasta kuvasta, miten intervallien alku- ja loppupisteiden pitää sijaita toistensa suhteen, jotta predikaatti toteutuu. Tässä malliksi näistä selkein, eli equal:
def equal(self, other):
    return self.start == other.start and self.end == other.end
  • Luokassa IntervalInterface on myös määritetty metodi interval_relation, joka saa parametreinaan kaksi intervallia ja palauttaa intervallien välisen suhteen, siis yhden yllä kuvatuista 13 mahdollisuudesta. Metodin palauttaman tuloksen pitää olla jokin tiedostossa allen_relation määritetyn enumeraatioluokan AllenRelation kentistä. Jos enumeraatiot eivät ole vielä tuttuja, lue niistä Pythonin dokumentaation luvusta The Python Standard Library: 8.13. enum — Support for enumerations.

    Esimerkki: jos on tehty sijoitukset i1 = Interval(10, 20) ja i2 = Interval(15, 17), pitäisi kutsun i1.interval_relation(i2) palauttaa tuloksenaan AllenRelation.contains.

    Toteutuksessasi voit käyttää jo määritettyjä predikaatteja Interval.before, Interval.meets, jne., tai jos haluat, voit tehdä koodin suoraan vertaamalla intervallien päätepisteitä. Jälkimmäinen tapa voi tuottaa tehokkaamman toteutuksen, mutta edellyttää huolellisuutta koodattaessa.

Palaute

Viitteitä

«  2.2. Pythonin poikkeukset   ::   Etusivulle   ::   3. Kierros 3 (7.2.2016 kello 23:59)  »