Viikko 6
HUOM: Kurssin Java-materiaalia ei enää ylläpidetä
- Materiaali ei siis välttämättä ole esimerkiksi käytettyjen kirjaston osalta ajankohtainen. Materiaalia voi kuitenkin seurata, mutta ongelmatilanteissa saattaa joutua soveltamaan ja nojautumaan kurssin ulkopuolisiin materiaaleihin.
- Tehtävien Java-versioiden kirjastoja ei ole päivitetty pitkään aikaan. Tehtävät on todettu toimivaksi Javan versiolla 11, Gradlen versiolla 6.7 ja JUnitin versiolla 4.13. Muiden versioiden käyttö omalla vastuulla.
Allaolevien tehtävien deadline on tiistai 10.12. klo 23:59
Apua tehtävien tekoon kurssin Discord-kanavalla, kampuksella pajassa BK107:
- ma 14-16
- to 13-15
- pe 12-14
Muista myös tämän viikon monivalintatehtävät, joiden deadline on ei tehtäviä .
Tehtävät 2-5 liittyvät materiaalin ohjelmistosuunnittelua käsittelevän osan 4 niihin lukuihin, joihin on merkitty [viikko 5] tai [viikko 6].
Tämän viikon monivalintatehtävät, deadline on poikkeuksellisesti vasta perjantaina 13.12. klo 23:59:00.
Typoja tai epäselvyyksiä tehtävissä?
Tee korjausehdotus editoimalla tätä tiedostoa GitHubissa.
Tehtävien palauttaminen
Tehtävät palautetaan GitHubiin, sekä merkitsemällä tehdyt tehtävät palautussovellukseen https://study.cs.helsinki.fi/stats/courses/ohtu2024
Katso tarkempi ohje palautusrepositorioita koskien täältä.
1. git: rebase [versionhallinta]
Tätä tehtävää ei palauteta mihinkään!
Lue http://git-scm.com/book/en/Git-Branching-Rebasing ja https://www.atlassian.com/git/tutorials/rewriting-history#git-rebase
Aikaansaa seuraavankaltainen tilanne
------- master \ \--- haara
“rebeissaa” haara masteriin, eli aikaansaa seuraava tilanne:
------- master \ \--- haara
Varmista komennolla gitk --all
että tilanne on haluttu.
“mergeä” master vielä haaraan:
------- \ master \--- haara
Lopputuloksena pitäisi siis olla lineaarinen historia ja master sekä haara samassa. Varmista jälleen komennolla gitk --all
että kaikki on kunnossa.
Poista branch haara. Etsi googlaamalla komento jolla saat tuhottua branchin.
2. Kyselykieli NHLStatistics-ohjelmaan, osa 1
Kurssirepositorion hakemistosta koodi/viikko6/QueryLanguage löytyy jälleen yksi versio tutusta NHL-tilastojen tarkasteluun tarkoitetusta ohjelmasta.
Tällä kertaa olemme kiinnostuneita tekemään hieman monimutkaisempia “kyselyjä” pelaajatietoihin, esim. listaa kaikki joukkueen PHI pelaajat joilla on vähintään 5 maalia ja vähintään 5 syöttöä.
Koodiin onkin luotu hieman valmista kalustoa josta pääset liikkeelle. Yllä olevan kyselyn voi suorittaa seuraavasti:
public static void main(String[] args) {
Statistics stats = new Statistics(new PlayerReaderImpl(" https://studies.cs.helsinki.fi/nhlstats/2021-22/players.txt"));
Matcher m = new And( new HasAtLeast(5, "goals"),
new HasAtLeast(5, "assists"),
new PlaysIn("PHI")
);
for (Player player : stats.matches(m)) {
System.out.println( player );
}
}
HUOM: jossain tehtäväpohjassa saattaa olla vielä käytössä vanha osoite datan hakuun (heroku…) eli jos törmäät ongelmaan, varmista että käytät yo urlia.
Luokalle Statistics on tehty metodi matches, joka palauttaa listan niistä pelaajista, joille parametrina annettu Matcher-rajapinnan toteuttava olio palauttaa true
Tutustu ohjelman rakenteeseen
- huomioi miten HasAtLeast käyttää Javan ns. reflektio-ominaisuutta kutsuessaan merkkijonoparametria vastaavaa metodia
- toinen huomioinarvoinen piirre on And-luokan konstruktorissa käytetty vaihtuvamittainen parametrilista, eli “vararg”, ks. lisää esim: https://www.javatpoint.com/varargs
Tee rajapinnan Matcher toteuttavat luokat, joiden avulla voit tehdä operaatiot
- All (tosi kaikille pelaajille)
- Not (parametrina olevan ehdon negaatio)
- HasFewerThan (HasAtLeast-komennon negaatio eli, esim. on vähemmän kuin 10 maalia)
Kaikille pelaajille tosi ehto all ei ole vielä tämän tehtävän kannalta kovin mielenkiintoinen, sitä pystyy kuitenkin hyödyntämään neljännessä tehtävässä.
Voit tarkistaa toteutuksesi toimivuuden tekemällä kyselyn
Matcher m = new And(
new Not( new HasAtLeast(1, "goals") ),
new PlaysIn("NYR")
);
vastauksena pitäisi olla joukkueen NYR pelaajista ne, joilla ei ole vähintään yht maalia, eli 0 maalia tehneet:
Sammy Blais NYR 0 + 4 = 4 Libor Hajek NYR 0 + 1 = 1 Tim Gettinger NYR 0 + 0 = 0 Anthony Greco NYR 0 + 0 = 0 Zac Jones NYR 0 + 2 = 2 Keith Kinkaid NYR 0 + 0 = 0 Igor Shesterkin NYR 0 + 0 = 0 Adam Huska NYR 0 + 0 = 0 Alexandar Georgiev NYR 0 + 0 = 0
Kyselyn
Matcher m = new And(
new HasFewerThan(1, "goals"),
new PlaysIn("NYR")
);
tulisi palauttaa täsmälleen sama lista.
Ehdon All
tulisi siis olla tosi kaikille pelaajille., Voit varmistaa sen toimivuudet kokeilemalla seuraavaa:
System.out.println(stats.matches(new All()).size());
Komennon tulisi tulostaa kaikkien pelaajien lukumäärä, joka on 964.
Ehto All
ei ole yksistään kovin hyödyllinen, mutta tulemme tarvitseman sitä pian.
3. Kyselykieli NHLStatistics-ohjelmaan, osa 2
Tee rajapinnan Matcher toteuttava Or, joka on tosi silloin jos ainakin yksi sen parametrina saamista ehdoista on tosi.
Kyselyn
Matcher m = new Or( new HasAtLeast(45, "goals"),
new HasAtLeast(70, "assists")
);
tulee palauttaa ne, joilla on vähintään 30 maalia tai 50 syöttöä, eli seuraava lista
Chris Kreider NYR 52 + 25 = 77
Artemi Panarin NYR 22 + 74 = 96
Auston Matthews TOR 60 + 46 = 106
Jonathan Huberdeau FLA 30 + 85 = 115
Alex Ovechkin WSH 50 + 40 = 90
Roman Josi NSH 23 + 73 = 96
Johnny Gaudreau CGY 40 + 75 = 115
Leon Draisaitl EDM 55 + 55 = 110
Connor McDavid EDM 44 + 79 = 123
Kirill Kaprizov MIN 47 + 61 = 108
Kyle Connor WPG 47 + 46 = 93
Kyselyn
Matcher m = new And(
new HasAtLeast(70, "points"),
new Or(
new PlaysIn("NYR"),
new PlaysIn("FLA"),
new PlaysIn("BOS")
)
);
tulee palauttaa kaikki vähintään 70 pistettä tehneet jotka pelaavat jossain seuraavista joukkueista NYR, FLA tai BOS. Lista näyttää seuraavalta:
Chris Kreider NYR 52 + 25 = 77
Mika Zibanejad NYR 29 + 52 = 81
Artemi Panarin NYR 22 + 74 = 96
Adam Fox NYR 11 + 63 = 74
Brad Marchand BOS 32 + 48 = 80
David Pastrnak BOS 40 + 37 = 77
Jonathan Huberdeau FLA 30 + 85 = 115
Aleksander Barkov FLA 39 + 49 = 88
Sam Reinhart FLA 33 + 49 = 82
Kyselyt perustuvat rakenteeltaan decorator-suunnittelumalliin, vastaavasti kuten materiaalin osan 4 esimerkissä dekoroitu pino. And- ja OR-muotoiset kyseltyt on muodostettu myös erään suunnittelumallin, compositen hengessä, ne ovat Matcher-rajapinnan toteuttavia olioita, jotka sisältävät itse monta Matcher-olioa. Niiden käyttäjä ei kuitenkaan tiedä sisäisestä rakenteesta mitään.
4. Parannettu kyselykieli, osa 1
Matcher-olioiden avulla tehtyä kyselykieltä vaivaa se, että kyselyjen rakentaminen on ikävää, sillä jokaista kyselyn osaa kohti on luotava new-komennolla uusi olio.
Tee materiaalin osassa 4 esitellyn pinorakentajan hengessä kyselyrakentaja, jonka avulla voit luoda Matcher-olioita.
Rakentaja voi toimia esim. seuraavaan tapaan.
Ensin kysely, joka palauttaa jokaisen pelaajan:
public static void main(String[] args) {
Statistics stats = new Statistics(new PlayerReaderImpl(" https://studies.cs.helsinki.fi/nhlstats/2021-22/players.txt"));
QueryBuilder query = new QueryBuilder();
Matcher m = query.build();
for (Player player : stats.matches(m)) {
System.out.println( player );
}
}
Tässä kyselyssä voi ja kannattaa hyödyntää aiemmin tehtyä All-matcheria.
Seuraavaksi kysely, missä tulostetaan pelaajat, joiden joukkue on NYR
public static void main(String[] args) {
Statistics stats = new Statistics(new PlayerReaderImpl(" https://studies.cs.helsinki.fi/nhlstats/2021-22/players.txt"));
QueryBuilder query = new QueryBuilder();
Matcher m = query.playsIn("NYR").build();
for (Player player : stats.matches(m)) {
System.out.println( player );
}
}
Seuraavaksi kysely, missä tulostetaan pelaajat joiden joukkue on NYR, joilla on vähintään 5 ja vähemmän kuin 10 maalia:
public static void main(String[] args) {
Statistics stats = new Statistics(new PlayerReaderImpl(" https://studies.cs.helsinki.fi/nhlstats/2021-22/players.txt"));
QueryBuilder query = new QueryBuilder();
Matcher m = query.playsIn("NYR")
.hasAtLeast(10, "goals")
.hasFewerThan(20, "goals").build();
for (Player player : stats.matches(m)) {
System.out.println( player );
}
}
Pelaajien lista on seuraava
Barclay Goodrow NYR 13 + 20 = 33
Jacob Trouba NYR 11 + 28 = 39
Adam Fox NYR 11 + 63 = 74
Alexis Lafrenière NYR 19 + 12 = 31
Peräkkäin ketjutetut ehdot siis toimivat “and”-periaatteella.
Tässä tehtävässä riittää, että kyselyrakentaja osaa muodostaa and-periaatteella yhdistettyjä ehtoja.
5. Parannettu kyselykieli, osa 2
Laajennetaan kyselyrakentajaa siten, että sen avulla voi muodostaa myös or-ehdolla muodostettuja kyselyjä. Or-ehdon sisältävä kysely voi olla muodostettu esim. seuraavasti:
QueryBuilder query = new QueryBuilder();
Matcher m1 = query.playsIn("PHI")
.hasAtLeast(10, "assists")
.hasFewerThan(5, "goals").build();
Matcher m2 = query.playsIn("EDM")
.hasAtLeast(50, "points").build();
Matcher m = query.oneOf(m1, m2).build();
Pelaajalistan tulisi olla:
Keith Yandle PHI 1 + 18 = 19 Rasmus Ristolainen PHI 2 + 14 = 16 Zach Hyman EDM 27 + 27 = 54 Ryan Nugent-Hopkins EDM 11 + 39 = 50 Leon Draisaitl EDM 55 + 55 = 110 Connor McDavid EDM 44 + 79 = 123
Tai sama ilman apumuuttujia:
Matcher m = query.oneOf(
query.playsIn("PHI")
.hasAtLeast(10, "assists")
.hasFewerThan(5, "goals").build(),
query.playsIn("EDM")
.hasAtLeast(50, "points").build()
).build();
On mahdollista ja jopa todennäköistä että ensimmäinen ratkaisusi ei toimi jos apumuuttujia ei käytetä. Mieti tarkkaan missä vika ja yritä korjata tilanne. Vaadittava muutos ei ole iso.
6. Pull request ja refaktorointia (tätä tehtävää ei lasketa versionhallintatehtäväksi)
Isoa projektia on vaikea ylläpitää yksin ja vielä vaikeampaa on löytää oikeat ratkaisut jokaiseen ongelmaan, kun ohjelmisto kasvaa. On vaikeaa hallita itse kaikkea ja jotkin osa-alueet eivät välttämättä edes miellytä ja niihin on siksi vaikea paneutua. Saatat löytää itsesi ajattelemasta vaikkapa: “Lukisipa joku tietorakenteiden asiantuntija tämän osuuden läpi ja tsekkaisi, että HashSet on nyt varmasti se tehokkain ratkaisu…”.
Ehkäpä et edes ajatellut asiaa, mutta joku silti näyttää, että binäärihakupuu onkin tilanteessa tehokkaampi ratkaisu, koodaa korjaukset puolestasi lähdekoodiin sekä tekee muutoksista pull requestin. Onneksi julkaisit projektisi Open Sourcena!
GitHub on täynnä Open Source -projekteja, jotka kaipaavat panostasi. Mikäs sen kivempaa, kuin käyttää muutama tunti suosikkirepositioriosi lähdekoodin parissa ja korvata sieltä huomaamasi epäelegantti ratkaisu paremmalla. Useilla repositorioilla on valmiit ohjeet muutosehdotusten tekemiseen repositorion juuresta löytyvässä tiedostossa Contributing.md. Tässä esimerkiksi bluebird.js:än CONTRIBUTING.md.
Tehtävänäsi on harjoitella muutosehdotuksen tekemistä “open source -projektiin” sekä vieraan koodin lukemista ja refaktorointia.
- Valitse yksi repositorio miniprojektien joukosta
- mielellään sellaisen ryhmän repositorio, jolla ei ole jo viittä pull requestia.
- ja luonnollisesti sellainen, jonka koodiin haluat tehdä jotain muutoksia
- Forkkaa repositorio
- Tee forkattuun repositorioon uusi branch nimellä “muutoksia”
- Tee luomaasi branchiin “tyhjä” pull request: lisää esimerkiksi yksi tyhjä rivi README.md:hen, pushaa uusi branch GitHubiin ja tee branchista pull request.
- Tyhjän pullrequestin tarkoituksena on varata sinulle paikka kyseisen repositorion muutoksentekijöiden joukosta. Haluamme, että kaikki ryhmät saavat suunilleen tasaisesti pull requesteja, eli jos repositoriossa on niitä jo runsaasti, etsi mielellään jokin muu repositorio.
- Etsi ryhmän lähdekoodista jotain refaktoroitavaa
- kyseessä ei tarvitse olla iso muutos, esimerkiksi muuttujan/metodin uudelleennimeäminenkin riittää
- Refaktoroi ja committaa
- Käy katsomassa tekemääsi tyhjää pullrequestia. Mitä tapahtui?
- Rebeissaa (ks. tämän viikon ensimmäinen tehtävä) luomasi branch paikalliseen master branchin päälle. Pushaa. Tapahtuiko pull requestissa muutoksia?
- Otsikoi tekemäsi pullrequest niin, että se kuvaa tekemiäsi muutoksia. Tarkenna otsikon alle mitä teit ja miksi.
- Jos ryhmä pyytää sinua tekemään muutoksia pull requestiisi, tee halutessasi tarvittavat muutokset ja committaa. Päivittyikö pullrequest?
- Kun ryhmä on hyväksynyt muutoksesi, voit poistaa luomasi branchin
Laita palautusrepositorioosi tiedosto PULL.md ja sen sisällöksi linkki pull requestiin.
Tehtävien palautus
Pushaa kaikki tekemäsi tehtävät (paitsi ne, joissa mainitaan, että tehtävää ei palauteta mihinkään) GitHubiin palautusrepositorioosi ja merkkaa tekemäsi tehtävät palautussovellukseen https://study.cs.helsinki.fi/stats/courses/ohtu2024