diff --git a/Tehtavananto.md b/Tehtavananto.md index 8105551311a1883df4b02fa14ac55085692cdac7..f51d799671439dcc6ae73503ea9ae545f246214d 100644 --- a/Tehtavananto.md +++ b/Tehtavananto.md @@ -124,12 +124,12 @@ halutaan molemmat testata erikseen. Toimiiko lajittelu oikein? ***B.*** Activation-luokassa on toteutettu rutiini parametricReLU. - Tutustu rutiiniin ja määrittele, mitä asioita testien pitää testata? -- Toteuta rutiiniin löytämiesi vaatimusten testaaminen assert lauseella. Toimiiko rutiini määrittelynsä mukaan? +[- Toteuta rutiiniin löytämiesi vaatimusten testaaminen assert lauseella. Toimiiko rutiini määrittelynsä mukaan? *Huomaa, että oletuksena assertions ei ole Javassa toiminnassa vaan se pitää kytkeä päälle erikseen Java virtuaalikoneen parametrillä -ea Parametrin saa asetettua käyttöön myös IDE-ympäristöissä* - +]() ***C.*** Palindrome-luokassa on rutiini convertToPalindrome, joka tekee syötteenä saamastaan merkkijonosta palindromin. - Tutustu rutiiniin ja määrittele, mitä asioita testien pitää testata? diff --git a/pom.xml b/pom.xml index c41821efbdf8aeae6637a1281a6f941947e17956..3263009e9faca278515bec224677b04213367064 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ <!-- Version numbers for various modules --> <jdk.version>17</jdk.version> <jqwik.version>1.7.1</jqwik.version> - <junit.version>5.9.1</junit.version> + <junit.version>5.9.2</junit.version> <junitplatform.version>1.9.1</junitplatform.version> </properties> diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Activation.java b/src/main/java/fi/utu/tech/ooj/exercise2/Activation.java deleted file mode 100644 index 6985b09db5e84cc379fd30ad1f210c1290b1f2df..0000000000000000000000000000000000000000 --- a/src/main/java/fi/utu/tech/ooj/exercise2/Activation.java +++ /dev/null @@ -1,11 +0,0 @@ -package fi.utu.tech.ooj.exercise2; - -public class Activation { - - public static float parametricReLU(float x, float a) { - if (x>0) { - return x; - } - return a*x; - } -} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Main.java b/src/main/java/fi/utu/tech/ooj/exercise2/Main.java index a51d8d2a7318b9ff030b44fbbfe14adf2fe00cc1..1c4fef7a93ae6d54705541afe16f46d94eee9c6b 100644 --- a/src/main/java/fi/utu/tech/ooj/exercise2/Main.java +++ b/src/main/java/fi/utu/tech/ooj/exercise2/Main.java @@ -1,6 +1,11 @@ package fi.utu.tech.ooj.exercise2; +import fi.utu.tech.ooj.exercise2.tehtava1.Laskutussovellus; +import fi.utu.tech.ooj.exercise2.tehtava3.Palindrome; +import fi.utu.tech.ooj.exercise2.tehtava3.Sorting; +import fi.utu.tech.ooj.exercise2.tehtava4.Kayttoliittyma; + import java.util.Arrays; public class Main { @@ -25,5 +30,9 @@ public class Main { System.out.println("Sorted array: " + Arrays.toString(someIntegers)); System.out.println(Palindrome.convertToPalindrome("jari")); + + Laskutussovellus laskutussovellus = new Laskutussovellus(); + + Kayttoliittyma kayttoliittyma = new Kayttoliittyma(); } } diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Sorting.java b/src/main/java/fi/utu/tech/ooj/exercise2/Sorting.java deleted file mode 100644 index 37736f01ead260d9a0af21ee6b38420f7d427158..0000000000000000000000000000000000000000 --- a/src/main/java/fi/utu/tech/ooj/exercise2/Sorting.java +++ /dev/null @@ -1,44 +0,0 @@ -package fi.utu.tech.ooj.exercise2; - -public class Sorting { - - public static void mergeSort(int[] a) { - int n = a.length; - if (n < 2) { - return; - } - int mid = n / 2; - int[] l = new int[mid]; - int[] r = new int[n - mid]; - - for (int i = 0; i < mid; i++) { - l[i] = a[i]; - } - for (int i = mid; i < n; i++) { - r[i - mid] = a[i]; - } - mergeSort(l); - mergeSort(r); - - merge(a, l, r, mid, n - mid); - } - - public static void merge(int[] a, int[] l, int[] r, int left, int right) { - - int i = 0, j = 0, k = 0; - while (i < left && j < right) { - if (l[i] <= r[j]) { - a[k++] = l[i++]; - } - else { - a[k++] = r[j++]; - } - } - while (i < left) { - a[k++] = l[i++]; - } - while (j < right) { - a[k++] = r[j++]; - } - } -} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2ohjelmalogiikka.java b/src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2ohjelmalogiikka.java deleted file mode 100644 index fd10d37d4f3415ea2010d08bef5bef2cc3b73c55..0000000000000000000000000000000000000000 --- a/src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2ohjelmalogiikka.java +++ /dev/null @@ -1,23 +0,0 @@ -package fi.utu.tech.ooj.exercise2; - -public class Tehtava2ohjelmalogiikka { - - private Tehtava2tiedostopalvelu tietopalvelu; - - public Tehtava2ohjelmalogiikka(Tehtava2tiedostopalvelu tieto) { - this.tietopalvelu = tieto; - } - - public void teeJotain() { - /* - Ohjelmassa käytetään rutiineita, jotka on toteutettu Tehtava2tiedostopalvelu-luokassa. - Tässä esimerkissä on kuvattu vain yksi ohjelmalogiikkaan kuuluva luokka. Todellisuudessa - luokkia on useita ja ne kaikki riippuvat suoraan konkreetista Tehtava2tiedostopalvelu-luokasta. - - tietopalvelu.haeTiedot(); - tietopalvelu.lisaaTieto(value); - tietopalvelu.muokkaaTieto(value, newValue) - tietopalvelu.poistaTieto(value) - */ - } -} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Asiakas.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Asiakas.java new file mode 100644 index 0000000000000000000000000000000000000000..580d9e1c8919ccf4342ea712fcdb9111b617e890 --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Asiakas.java @@ -0,0 +1,94 @@ +package fi.utu.tech.ooj.exercise2.tehtava1; + +/* Luokka "Asiakas" sisältää omana yksityisenä kenttänään kaikki tallennetut tiedot. + Tallennan kaikki tiedot merkkijonoina, sillä postinumero ja puhelinnumero eivät ole täysin + kokonaislukumuotoisia - ne sisältävät nollia luvun alussa, jotka muussa tapauksessa + sieventyisivät pois. + + Luokan olisi voinut toteuttaa myös tietueena, mutta se ei mahdollistaisi helposti + tulevaisuudessa sitä, että asiakkaan puhelinnumeron tai kotisoitteen voisi vaihtaa + (tietue säilyttää sille asetetut arvot muuttumattomina). + + Kaikki tiedot on kapseloitu luokan sisään siten, ettei niitä voi tarkastella ulkopuolelta + käsin kuin havainnointimetodeilla. Tämä selkeyttää sovelluksen rakennetta. + Konstruktori ei suostu vastaanottamaan null-muotoisia objekteja tai tyhjiä merkkijonoja + - tällä haluan ensinnäkin ohjata käyttäjää syöttämään rekisteriin kaikki vaaditut tiedot sekä + ennaltaehkäisemään NullReferenceExceptionia ohjelman myöhemmissä suoritusvaiheissa. + */ +public class Asiakas { + /* .classInvariant() GetNimi() != "" && GetKatuosoite() != "" && GetPostinumero() != "" + && GetPostitoimipaikka() != "" && GetPuhelinnumero() != "" + .classInvariantPrivate() this.nimi != "" && this.katuosoite != "" && this.postinumero != "" + && this.postitoimipaikka != "" this.puhelinnumero != "" + && GetNimi() == this.nimi && GetKatuosoite() == this.katuosoite + && GetPostinumero() == this.postinumero + && GetPuhelinnumero() == this.puhelinnumero*/ + + private String nimi; + private String katuosoite; + private String postinumero; + private String postitoimipaikka; + private String puhelinnumero; + + /* @.pre nimi!= null && nimi != "" && katuosoite != null && katuosoite != "" + && postinumero != null && postinumero != "" + && postitoimipaikka != null && postitoimipaikka != "" + && puhelinnumero != null && puhelinnumero != "" + @.post GetNimi() == nimi && GetKatuosoite() == katuosoite && GetPostinumero() == postinumero + && GetPostitoimipaikka() == postitoimipaikka && GetPuhelinnumero() == puhelinnumero + @throws IllegalArgumentException + Nostetaan, jos jokin argumenttien merkkijonoista on tyhjä arvo (null) + tai tyhjä merkkijono ("") + */ + public Asiakas(String nimi, String katuosoite, String postinumero, + String postitoimipaikka, String puhelinnumero) throws IllegalArgumentException { + if ((nimi != null && !nimi.equals("")) && (katuosoite != null && !katuosoite.equals("")) && + (postinumero != null && !postinumero.equals("")) && + (postitoimipaikka != null && !postitoimipaikka.equals("")) && + (puhelinnumero != null && !puhelinnumero.equals(""))) { + this.nimi = nimi; + this.katuosoite = katuosoite; + this.postinumero = postinumero; + this.postitoimipaikka = postitoimipaikka; + this.puhelinnumero = puhelinnumero; + } else { + throw new IllegalArgumentException("Metodi vaatii asetetun nimen, katuosoitteen," + + " postinumeron, postitoimipaikan ja puhelinnumeron"); + } + } + + /* @.pre true + @.post RESULT = this.nimi + */ + public String GetNimi() { + return nimi; + } + + /* @.pre true + @.post RESULT = this.katuosoite + */ + public String GetKatuosoite() { + return katuosoite; + } + + /* @.pre true + @.post RESULT = this.postinumero + */ + public String GetPostinumero() { + return postinumero; + } + + /* @.pre true + @.post RESULT = this.postitoimipaikka + */ + public String GetPostitoimipaikka() { + return postitoimipaikka; + } + + /* @.pre true + @.post RESULT = this.puhelinnumero + */ + public String GetPuhelinnumero() { + return puhelinnumero; + } +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Asiakasrekisteri.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Asiakasrekisteri.java new file mode 100644 index 0000000000000000000000000000000000000000..95607412cdae804180f1bc9354d4b78636125a73 --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Asiakasrekisteri.java @@ -0,0 +1,87 @@ +package fi.utu.tech.ooj.exercise2.tehtava1; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.NoSuchElementException; + +public class Asiakasrekisteri { + /* + .classInvariant() + .classInvariantPrivate() asiakkaat != null + */ + private HashMap<Asiakas, Laskut> asiakkaat; + + /* @.pre true + @.post GetAsiakkaat() != null + */ + public Asiakasrekisteri() { + asiakkaat = new HashMap<>(); + } + + /* @.pre asiakas != null + @.post this.GetAsiakkaat().CONTAINS(asiakas) + @.throws IllegalArgumentException + Nostetaan, jos asiakas on null (tyhjä arvo) + */ + public void LisaaAsiakas(Asiakas asiakas) throws IllegalArgumentException { + if (asiakas != null) { + asiakkaat.put(asiakas, new Laskut()); + } else { + throw new IllegalArgumentException("Parametrinä annettua asiakasta ei ole määritelty (arvo on null)"); + } + } + + /* @.pre asiakas != null && lasku != null + @.post GetLaskut().CONTAINS(lasku) + @.throws IllegalArgumentException + Nostetaan, jos parametrinä annettua laskua ei ole määritelty (arvon ollessa siten null) + */ + public void LisaaLasku(Asiakas asiakas, Lasku lasku) throws IllegalArgumentException { + if (asiakkaat.containsKey(asiakas)) { + asiakkaat.get(asiakas).LisaaLasku(lasku); + } else { + LisaaAsiakas(asiakas); + } + } + + + /* @.pre true + @.post RESULT = ArrayList<Lasku>() + */ + public ArrayList<Lasku> GetLaskut() { + ArrayList<Lasku> palautettavatLaskut = new ArrayList<>(); + for(Laskut laskut : asiakkaat.values()) { + for(Lasku lasku : laskut.GetLaskut()) { + palautettavatLaskut.add(lasku); + } + } + return palautettavatLaskut; + } + + /* @.pre true + @.post RESULT = this.asiakkaat + */ + public ArrayList<Asiakas> GetAsiakkaat() { + return new ArrayList<>(asiakkaat.keySet()); + } + + /* @.pre asiakas != null && GetAsiakkaat().CONTAINS(Asiakas) + @.post RESULT == instanceof(Laskut) + @.throws IllegalArgumentException, NoSuchElementException + Nostetaan IllegalArgumentException, + jos metodin parametrinä annettu Asiakas-luokan olio on tyhjä (null) + Nostetaan NoSuchElementException, + jos metodin parametrinä annettua Asiakas-luokan oliota ei löydy luokkaan kapseloidusta kokoelmasta + */ + public Laskut GetAsiakkaanLaskut(Asiakas asiakas) throws IllegalArgumentException, NoSuchElementException { + if (asiakas != null) { + if (asiakkaat.containsKey(asiakas)) { + return asiakkaat.get(asiakas); + } else { + throw new NoSuchElementException("Parametrinä annettua asiakasta ei ole lisätty asiakaslistaan"); + } + } else { + throw new IllegalArgumentException("Parametrinä annettua asiakasta ei ole määritelty (arvo on null)"); + } + } +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Lasku.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Lasku.java new file mode 100644 index 0000000000000000000000000000000000000000..9b4d14cd3acb42bd6d0d7651252140de797a4285 --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Lasku.java @@ -0,0 +1,168 @@ +package fi.utu.tech.ooj.exercise2.tehtava1; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.NoSuchElementException; + +/* Luokka sisältää yksittäisen laskun toiminnallisuuden. + Laskussa on rivejä, joista jokainen edustaa yksittäistä tuotetta. + Mikäli laskuun yritetään lisätä useita samoja tuotteita, yhdistetään ne samalle riville. + Ratkaisun seurauksena kaikille saman tuotteen esiintymille on asetettu yhteinen alennuksensa, + joka ei välttämättä ole intuitiivisin ratkaisu, mutta mielestäni ohjelmoinnillisesti tyylikkäin. + + Tuotteet on järjestetty hajautustauluun, jotta tuotteiden hakeminen taulusta nopeutuisi. + Luokka sisältää vain yhden kentän, joka on edellämainittu hajautustaulu. Kenttä on kapseloitu + osaksi luokkaa. + + Toteutus ei sisällä tietoa laskun + omistajasta (asiakkaasta), sillä se säilötään asiakasrekisterin hajautustaulussa. Lisäksi tämä + toteutus mahdollistaa Lasku-luokan uudelleenkäytön muissakin yhteyksissä, joihin ei välttämättä + liity Asiakas-luokan oliota. Vaihtoehtoisesti vastaavan muunneltavuuden olisi voinut toteuttaa + myös siten, että asiakas-luokka olisi periytetty jostain abstraktista luokasta, mutta se olisi + ollut tässä yhteydessä nähdäkseni liian työlästä. + */ +public class Lasku { + /* @.classInvariant true + @.classInvariantPrivate tuotteet != null && FOR (x : tuotteet.values()) => x = [], x.length = 2 + + Arvoksi asetetun taulukon ensimmäinen sarake kertoo tuotteen lukumäärän, toinen alennuksen + */ + private HashMap<Tuote, double[]> tuotteet; + + /* @.pre true + @.post GetTuotteet != null + */ + public Lasku() { + tuotteet = new HashMap<>(); + } + + /* @.pre (tuote) != null + @.post GetTuotteet().CONTAINS(tuote) + @.throws IllegalArgumentException + Nostetaan, jos argumenteissa annettua muuttujaa "tuote" ei ole määritelty + eli sen arvo on "null" + */ + public void LisaaTuote(Tuote tuote) throws IllegalArgumentException { + if (tuote != null) { + if (!tuotteet.containsKey(tuote)) { + tuotteet.put(tuote, new double[]{1,0}); + } else { + tuotteet.get(tuote)[0]++; + } + } else { + throw new IllegalArgumentException("Parametrinä annettua tuotetta ei ole määritelty (arvo on null"); + } + } + + /* @.pre (tuote) != null, (lukumaara) > 0, (alennus) > 0 && (alennus) <= 100 + @.post GetTuotteet.CONTAINS(tuote), + @.throws IllegalArgumentException, NoSuchElementException + Nostaa IllegalArgumentException, kun parametrinä annettu tuote on tyhjä arvo + TAI tuotteen lukumääräksi on asetettu 0 tai pienempi luku + Nostaa NoSuchElementException, jos metodin käyttämä SetAlennus-asetusmetodi + ei löydä parametrinä annettua tuotetta hajautustaulusta + */ + public void LisaaTuote(Tuote tuote, int lukumaara, double alennus) throws IllegalArgumentException, + NoSuchElementException{ + if (lukumaara > 0) { + LisaaTuote(tuote); + tuotteet.get(tuote)[0] += (lukumaara-1); + SetAlennus(tuote, alennus); + } else { + throw new IllegalArgumentException("Lukumäärän on oltava suurempi kuin nolla"); + } + } + + /* @.pre (tuote) != null && GetTuotteet().CONTAINS(Tuote) + @.post true + @.throws IllegalArgumentException, NoSuchElementException + Nostaa IllegalArgumentException, kun parametrinä annettu tuote on tyhjä arvo + TAI jos parametriksi "alennus" on syötetty negatiivinen luku. + Nostaa NoSuchElementException, kun tuotetta ei ole lisätty laskulle + */ + public void SetAlennus(Tuote tuote, double alennus) throws IllegalArgumentException, + NoSuchElementException { + if (tuote != null) { + if (tuotteet.containsKey(tuote)) { + if(alennus > 0 && alennus <=100) { + tuotteet.get(tuote)[1] = alennus; + } else { + throw new IllegalArgumentException("Alennuksen on oltava suurempi kuin nolla"); + } + } else { + throw new NoSuchElementException("Tuotetta ei löytynyt laskulta"); + } + } else { + throw new IllegalArgumentException("Parametrinä annettua tuotetta ei ole määritelty (arvo on null)"); + } + } + + /* @.pre (tuote) != null && GetTuotteet().CONTAINS(Tuote) + @.post true + @.throws IllegalArgumentException, NoSuchElementException + Nostaa IllegalArgumentException, kun parametrinä annettu tuote on tyhjä arvo. + Nostaa NoSuchElementException, kun tuotetta ei ole lisätty laskulle + */ + public double GetAlennus(Tuote tuote) throws IllegalArgumentException, NoSuchElementException { + if (tuote != null) { + if (tuotteet.containsKey(tuote)) { + double aHinta = tuote.GetVerollinenHinta(); + double lkm = tuotteet.get(tuote)[0]; + double alennus = tuotteet.get(tuote)[1]; + + return alennus; + } else { + throw new NoSuchElementException("Tuotetta ei löytynyt laskulta"); + } + } else { + throw new IllegalArgumentException("Parametrinä annettua tuotetta ei ole määritelty (arvo on null)"); + } + } + + /* @.pre (tuote) != null && GetTuotteet().CONTAINS(Tuote) + @.post true + @.throws IllegalArgumentException, NoSuchElementException + Nostaa IllegalArgumentException, kun parametrinä annettu tuote on tyhjä arvo. + Nostaa NoSuchElementException, kun tuotetta ei ole lisätty laskulle + */ + public double GetLukumaara(Tuote tuote) throws IllegalArgumentException, NoSuchElementException { + if (tuote != null) { + if (tuotteet.containsKey(tuote)) { + return tuotteet.get(tuote)[0]; + } else { + throw new NoSuchElementException("Tuotetta ei löytynyt laskulta"); + } + } else { + throw new IllegalArgumentException("Parametrinä anenttua tuotetta ei ole määritelty (arvo on null)"); + } + } + + /* @.pre (tuote) != null && GetTuotteet().CONTAINS(Tuote) + @.post true + @.throws IllegalArgumentException, NoSuchElementException + Nostaa IllegalArgumentException, kun parametrinä annettu tuote on tyhjä arvo. + Nostaa NoSuchElementException, kun tuotetta ei ole lisätty laskulle + */ + public double GetHinta(Tuote tuote) throws IllegalArgumentException, NoSuchElementException { + if (tuote != null) { + if (tuotteet.containsKey(tuote)) { + double lukumaara = tuotteet.get(tuote)[0]; + double alennus = tuotteet.get(tuote)[1]; + + double hinta = tuote.GetVerollinenHinta() * lukumaara - alennus; + return hinta; + } else { + throw new NoSuchElementException("Tuotetta ei löytynyt laskulta"); + } + } else { + throw new IllegalArgumentException("Parametrinä anenttua tuotetta ei ole määritelty (arvo on null)"); + } + } + + /* @.pre true + @.post RESULT == ArrayList<Tuote> + */ + public ArrayList<Tuote> GetTuotteet() { + return new ArrayList<>(tuotteet.keySet()); + } +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Laskut.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Laskut.java new file mode 100644 index 0000000000000000000000000000000000000000..ca0089f74bf0ee81bdf33f7df64379ec33a55b24 --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Laskut.java @@ -0,0 +1,50 @@ +package fi.utu.tech.ooj.exercise2.tehtava1; + +import fi.utu.tech.ooj.exercise2.tehtava1.Lasku; + +import java.util.ArrayList; + +/* + Laskut on kapseloitu luokka, joka sisältää yksinkertaisesti ArrayList-muotoisen kentän + Lasku-luokan olioiden säilyttämiseen, luokan ArrayList-muotoisen laskut-nimisen + olion asetuksen Laskut-luokankonstuktorissa, LisääLasku-asetusmetodin ja GetLaskut- + havainnointimetodin. Toteutus ei sisällä tietoa laskujen omistajasta (asiakkaasta), sillä ne + säilötään asiakasrekisterin hajautustaulussa. Lisäksi tämä toteutus mahdollistaa Laskut-luokan + uudelleenkäytön muissakin yhteyksissä, joihin ei välttämättä liity Asiakas-luokan oliota. + Vaihtoehtoisesti vastaavan muunneltavuuden olisi voinut toteuttaa myös siten, että + asiakas-luokka olisi periytetty jostain abstraktista luokasta, mutta se olisi ollut tässä + yhteydessä nähdäkseni liian työlästä. + */ +public class Laskut { + /* @.classInvariant true + @.classInvariantPrivate laskut != null + */ + private ArrayList<Lasku> laskut; + + /* @.pre true + @-post GetLaskut() != null + */ + public Laskut() { + laskut = new ArrayList<>(); + } + + /* @.pre lasku != null + @.post GetLaskut().CONTAINS(lasku) + @.throws IllegalArgumentException + Nostetaan, jos parametrinä annettua laskua ei ole määritelty (arvon ollessa siten null) + */ + public void LisaaLasku(Lasku lasku) throws IllegalArgumentException { + if (lasku != null) { + laskut.add(lasku); + } else { + throw new IllegalArgumentException("Parametrinä annettua laskua ei ole määritelty (arvo on null)"); + } + } + + /* @.pre true + @.post RESULT = ArrayList<Lasku> + */ + public ArrayList<Lasku> GetLaskut() { + return laskut; + } +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Laskutussovellus.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Laskutussovellus.java new file mode 100644 index 0000000000000000000000000000000000000000..93c23233fa8f4e860e0f3464e84449119b000b06 --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Laskutussovellus.java @@ -0,0 +1,42 @@ +package fi.utu.tech.ooj.exercise2.tehtava1; + +public class Laskutussovellus { + private Tuotteet tuotteet; + private Asiakasrekisteri asiakasrekisteri; + + public Laskutussovellus() { + tuotteet = new Tuotteet(); + asiakasrekisteri = new Asiakasrekisteri(); + + Tuote lappari = new Tuote("Läppäri", 900, 24); + Tuote hiiri = new Tuote("Hiiri", 45, 24); + Tuote energiajuoma = new Tuote("Energiajuoma, 6-pack", 10, 12); + + Asiakas matti = new Asiakas("Matti Meikäläinen", "Ylälahdentie 6b", + "58500", "Punkaharju", "0501234567"); + + asiakasrekisteri.LisaaAsiakas(matti); + Lasku lasku = new Lasku(); + lasku.LisaaTuote(lappari); + lasku.LisaaTuote(hiiri); + lasku.LisaaTuote(hiiri); + lasku.LisaaTuote(energiajuoma, 2, 5); + asiakasrekisteri.LisaaLasku(matti, lasku); + + System.out.println("ESIMERKKI LASKUTUSSOVELLUKSEN TOIMINNASTA:"); + + for(Asiakas asiakas : asiakasrekisteri.GetAsiakkaat()) { + System.out.println("Asiakas: " + asiakas.GetNimi()); + for(Lasku asLasku : asiakasrekisteri.GetAsiakkaanLaskut(asiakas).GetLaskut()) { + for(Tuote tuote: asLasku.GetTuotteet()) { + System.out.println("Tuotteen nimi: " + tuote.GetNimi() + ", Normaalihinta: " + + tuote.GetNormaalihinta() + ", Vero-%: " + tuote.GetAlvProsentti() + + ", Verollinen hinta: " + tuote.GetVerollinenHinta() + ", Kappalemäärä: " + + asLasku.GetLukumaara(tuote) + ", Alennus " + asLasku.GetAlennus(tuote) + + ", Yhteishinta: " + asLasku.GetHinta(tuote)); + } + } + } + } + +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Tuote.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Tuote.java new file mode 100644 index 0000000000000000000000000000000000000000..de1d69936456d90b58fa0d756d06227b573e906e --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Tuote.java @@ -0,0 +1,83 @@ +package fi.utu.tech.ooj.exercise2.tehtava1; + +/* Tuote-luokka sisältää kapseloituna nimen, normaalihinnan ja alv-prosentin. + Luokan konstuktori heittää IllegalArgumentException-poikkeuksen, jos sen argumentiksi + syötetään tyhjä arvo (null) tai tyhjä merkkijono. Normaalihinnan on oltava mielekäs, eli > 0. + Alv-prosentin on oltava jokseenkin järkevä, joten olen asettanut sille ehdot 0 <= alvProsentti <= 50 + + Tuote-luokassa on myös oma metodinsa, joka laskee tuotteen hinnasta ja alv-prosentista tuotteen + verollisen hinnan. Lähden toteutuksessa liikkeelle siitä, että rivikohtainen alennus annetaan + nimenomaan verollisesta hinnasta, ei verottomasta. + */ +public class Tuote { + /* classInvariant() GetNimi() != "" && GetNormaalihinta() > 0 + && GetAlvProsentti() >= 0 && GetAlvProsentti() <= 50 + classInvariantPrivate() nimi != null + */ + private String nimi; + + private double normaalihinta; + + private double alvProsentti; + + /* @.pre nimi != null && !nimi.equals("") && normaalihinta > 0 + && alvProsentti >= 0 && alvProsentti <= 50 + @.post GetNimi().equals(nimi) && this.toString().equals(nimi) && GetNormaalihinta() == normaalihinta + && GetAlvProsentti() == alvProsentti && GetVerollinenHinta() + == (1 + (alvProsentti/100)) * normaalihinta + @.throws IllegalArgumentException + Nostetaan, jos merkkijonoa "nimi" ei ole määritelty tai se on tyhjä merkkijono + TAI jos "normaalihinta" <= 0 TAI jos alvProsentti ei ole välillä 0-50 + */ + public Tuote(String nimi, double normaalihinta, double alvProsentti) throws IllegalArgumentException { + if (nimi != null && !nimi.equals("") && normaalihinta > 0 && alvProsentti >= 0 && alvProsentti <= 50) { + this.nimi = nimi; + this.normaalihinta = normaalihinta; + this.alvProsentti = alvProsentti; + } else { + throw new IllegalArgumentException("Jokin seuraavista tapahtui:" + + "(A) nimeä ei ole määritelty (sen arvo on tyhjä)" + + "tai se on tyhjä merkkijono. (B) Tuotteen normaalihinta ei ole suurempi kuin 0" + + " (C) Tuotteen alv-prosentti ei ole välillä 0-50"); + } + this.nimi = nimi; + this.normaalihinta = normaalihinta; + this.alvProsentti = alvProsentti; + } + + /* @.pre true + @.post RESULT == (nimi) + */ + public String GetNimi() { + return nimi; + } + + /* @.pre true + @.post RESULT == (normaalihinta) + */ + public double GetNormaalihinta() { + return normaalihinta; + } + + /* @.pre true + @.post RESULT == (alvProsentti) + */ + public double GetAlvProsentti() { + return alvProsentti; + } + + /* @.pre true + @.post RESULT == (1 + GetAlvProsentti()) * GetNormaalihinta(); + */ + public double GetVerollinenHinta() { + return (1 + (alvProsentti/100)) * normaalihinta; + } + + /* @.pre true + @.post RESULT = GetNimi() + */ + @Override + public String toString() { + return GetNimi(); + } +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Tuotteet.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Tuotteet.java new file mode 100644 index 0000000000000000000000000000000000000000..a76ea876100e59fb84b0128d1fb10c8dafa51b68 --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava1/Tuotteet.java @@ -0,0 +1,44 @@ +package fi.utu.tech.ooj.exercise2.tehtava1; + +import fi.utu.tech.ooj.exercise2.tehtava1.Tuote; + +import java.util.ArrayList; + +/* + Tuotteet on kapseloitu luokka, joka sisältää yksinkertaisesti ArrayList-muotoisen kentän + Tuote-luokan olioiden säilyttämiseen, luokan ArrayList-muotoisen tuotteet-nimisen olion + asetuksen Tuotteet-luokan konstuktorissa, LisääTuote-asetusmetodin ja GetTuotteet-havainnointimetodin. + */ +public class Tuotteet { + /* @.classInvariant true + @.classInvariantPrivate tuotteet != null + */ + private ArrayList<Tuote> tuotteet; + + /* @.pre true + @-post GetTuotteet() != null + */ + public Tuotteet() { + tuotteet = new ArrayList<>(); + } + + /* @.pre tuote != null + @.post GetTuotteet().CONTAINS(tuote) + @.throws IllegalArgumentException + Nostetaan, jos parametrinä annettua tuotetta ei ole määritelty (arvon ollessa siten null) + */ + public void LisaaTuote(Tuote tuote) throws IllegalArgumentException { + if (tuote != null) { + tuotteet.add(tuote); + } else { + throw new IllegalArgumentException("Parametrinä annettua tuotetta ei ole määritelty (arvo on null)"); + } + } + + /* @.pre true + @.post RESULT = ArrayList<Tuote> + */ + public ArrayList<Tuote> GetTuotteet() { + return tuotteet; + } +} \ No newline at end of file diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava2/Tehtava2ohjelmalogiikka.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava2/Tehtava2ohjelmalogiikka.java new file mode 100644 index 0000000000000000000000000000000000000000..e57f2d9f6a215aa87114708e7ad67e8a51da5fae --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava2/Tehtava2ohjelmalogiikka.java @@ -0,0 +1,45 @@ +package fi.utu.tech.ooj.exercise2.tehtava2; + +import fi.utu.tech.ooj.exercise2.tehtava2.tietoyhteys.Tiedostopalvelu; + +/* +Toteutin toteutuksen luomalla rajapinnan Tiedotopalvelu, jonka +Tehtava2tiedostopalvelu- ja Tehtava2tietokanta -luokat toteuttavat. +Mielestäni rajapinta oli järkevä ratkaisu, sillä jos olisin periyttänyt luokkien yhteisen +toiminnallisuuden jostain abstraktista luokasta tai konkreetista kattoluokasta, +tarkoittaisi se sitä, etteivät aliluokat voi periä mitään muita luokkia: Java ei nimittäin +ohjelmointikielenä tue moniperintää. Onnistuessaankin moniperintä voisi monimutkaistaa koodia +ja siten johtaa turhiin poikkeuksiin ohjelmakoodia suorittaessa. Tiedostopalvelu-toiminnan periyttäminen +saattaisi johtaa myöhemmin kehitysvaiheessa arkkitehtuurisiin ongelmiin. Lisäksi oletuksena periytetty +toiminnallisuus pitäisi ohittaa (override) tai jättää kattoluokassa määrittelemättä (abstraktiksi), +mikäli alaluokissa halutaan tehdä omia toteutuksia yhteisen toiminnallisuuden suhteen. Rajapinnan +toteuttaminen olikin siten nähdäkseni ilmeinen ratkaisu. Rajapintatoteutuksen heikkoutena on tietenkin, että se vaatii täysin +samanlaisenkin toiminnallisuuden ohjelmoinnin useaan kertaan ja siten voi johtaa koodin tarpeettomaan +kopiointiin. Toisaalta, mikäli alun perin haasteena oli saman toiminnon eriävien toteutuksien käsittely, +vastaa rajapintojen hyödyntäminen siihen erinomaisesti. Mikäli toiminnallisuudet vain periytettäisiin +kattoluokasta käsin, voisi alempiin luokkiin periytyä myös sellaisia ominaisuuksia, joille ei ole +perivissä luokissa käyttöä. Java-kielessä tällaisia toiminnallisuuksia olisi mahdoton piilottaa. + */ +public class Tehtava2ohjelmalogiikka { + + private Tiedostopalvelu tietopalvelu; + + /* Tehtava2ohjelmalogiikka-konstuktorin parametreissä voi asettaa toteuttajaksi + Minkä tahansa Tiedostopalvelu-rajapinnan täyttävän luokan */ + public Tehtava2ohjelmalogiikka(Tiedostopalvelu tieto) { + this.tietopalvelu = tieto; + } + + public void teeJotain() { + /* + Ohjelmassa käytetään rutiineita, jotka on toteutettu Tehtava2tiedostopalvelu-luokassa. + Tässä esimerkissä on kuvattu vain yksi ohjelmalogiikkaan kuuluva luokka. Todellisuudessa + luokkia on useita ja ne kaikki riippuvat suoraan konkreetista Tehtava2tiedostopalvelu-luokasta. + + tietopalvelu.haeTiedot(); + tietopalvelu.lisaaTieto(value); + tietopalvelu.muokkaaTieto(value, newValue) + tietopalvelu.poistaTieto(value) + */ + } +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2tiedostopalvelu.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava2/tietoyhteys/Tehtava2tiedostopalvelu.java similarity index 80% rename from src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2tiedostopalvelu.java rename to src/main/java/fi/utu/tech/ooj/exercise2/tehtava2/tietoyhteys/Tehtava2tiedostopalvelu.java index 3eb62bbfd7c2a3fa267a6856711752dd8f6fce8d..764866ffd6338a711433a32fd40fd794aef3f578 100644 --- a/src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2tiedostopalvelu.java +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava2/tietoyhteys/Tehtava2tiedostopalvelu.java @@ -1,8 +1,8 @@ -package fi.utu.tech.ooj.exercise2; +package fi.utu.tech.ooj.exercise2.tehtava2.tietoyhteys; import java.util.List; -public class Tehtava2tiedostopalvelu<T> { +public class Tehtava2tiedostopalvelu<T> implements Tiedostopalvelu<T> { public void lisaaTieto(T value) { diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2tietokanta1.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava2/tietoyhteys/Tehtava2tietokanta1.java similarity index 74% rename from src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2tietokanta1.java rename to src/main/java/fi/utu/tech/ooj/exercise2/tehtava2/tietoyhteys/Tehtava2tietokanta1.java index 06f5af4617e33534495d435ce92ac84ed579af94..c2fc3354732ebae955503003ffebd824e105f7d3 100644 --- a/src/main/java/fi/utu/tech/ooj/exercise2/Tehtava2tietokanta1.java +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava2/tietoyhteys/Tehtava2tietokanta1.java @@ -1,8 +1,8 @@ -package fi.utu.tech.ooj.exercise2; +package fi.utu.tech.ooj.exercise2.tehtava2.tietoyhteys; import java.util.List; -public class Tehtava2tietokanta1<T> { +public class Tehtava2tietokanta1<T> implements Tiedostopalvelu<T> { public void lisaaTieto(T value) { //Toteutus poistettu. Se on merkityksetön tehtävän kannalta. @@ -16,7 +16,7 @@ public class Tehtava2tietokanta1<T> { public void muokkaaTieto(T value, T newValue) { //Toteutus poistettu. Se on merkityksetön tehtävän kannalta. } - public void poistaTieto(T value) { + public void poistaTieto(T value) { //Toteutus poistettu. Se on merkityksetön tehtävän kannalta. } } diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava2/tietoyhteys/Tiedostopalvelu.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava2/tietoyhteys/Tiedostopalvelu.java new file mode 100644 index 0000000000000000000000000000000000000000..9c452a753b87c66bbb2f165227342c597cf62cdf --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava2/tietoyhteys/Tiedostopalvelu.java @@ -0,0 +1,14 @@ +package fi.utu.tech.ooj.exercise2.tehtava2.tietoyhteys; + +import java.util.List; + +public interface Tiedostopalvelu<T> { + void lisaaTieto (T value); + List<T> haeTiedot(); + + void muokkaaTieto(T value, T newValue); + + void poistaTieto(T value); + + +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava3/Activation.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava3/Activation.java new file mode 100644 index 0000000000000000000000000000000000000000..a96a255d52712acc007faf48f6d69b98315d89bd --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava3/Activation.java @@ -0,0 +1,20 @@ +package fi.utu.tech.ooj.exercise2.tehtava3; + +public class Activation { + + /* + Jotta metodi toimisi kuin parametrisen ReLU-funktion kuuluu, sen tulee + palauttaa x, jos x > 0 ja muussa tapauksessa parametri a * x. + Tätä voidaan testata seuraavilla testeillä + + (1) Palauttaako funktio x:n, kun x = 1? + (2) Palauttaako funtio a * x, kun x on 0 tai negatiivinen luku ja + a satunnaisluku välillä (0.01-1)? + */ + public static float parametricReLU(float x, float a) { + if (x>0) { + return x; + } + return a*x; + } +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Car.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava3/Car.java similarity index 93% rename from src/main/java/fi/utu/tech/ooj/exercise2/Car.java rename to src/main/java/fi/utu/tech/ooj/exercise2/tehtava3/Car.java index caafc984eb47b91480b18aa5e99dbb675fc66991..371bd7198096182f96c8ee10d949d35d6f6e9b42 100644 --- a/src/main/java/fi/utu/tech/ooj/exercise2/Car.java +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava3/Car.java @@ -1,7 +1,12 @@ -package fi.utu.tech.ooj.exercise2; +package fi.utu.tech.ooj.exercise2.tehtava3; import java.time.Year; +/* +***D.*** Tutustu tehtävä pohjasta löytyvään Car-luokkaan. +- Suunnittele yksikkötestit, jotka tarkastavat säilyttävätkö luokan rutiinit luokkainvariantin vaatimukset. +- Toteuta edellä suunnitellut yksikkötestit käyttäen JUnit-kirjastoa. + */ public class Car { /* diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/Palindrome.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava3/Palindrome.java similarity index 80% rename from src/main/java/fi/utu/tech/ooj/exercise2/Palindrome.java rename to src/main/java/fi/utu/tech/ooj/exercise2/tehtava3/Palindrome.java index c338723fc971a4349eaacb1fd395afc7ba234699..f9e7b3cb90a62cd988f54c6bf6082b0b87c24ea3 100644 --- a/src/main/java/fi/utu/tech/ooj/exercise2/Palindrome.java +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava3/Palindrome.java @@ -1,4 +1,4 @@ -package fi.utu.tech.ooj.exercise2; +package fi.utu.tech.ooj.exercise2.tehtava3; public class Palindrome { diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava3/Sorting.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava3/Sorting.java new file mode 100644 index 0000000000000000000000000000000000000000..81107681c29d4ab5d605d79df77ade01de012ea2 --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava3/Sorting.java @@ -0,0 +1,70 @@ +package fi.utu.tech.ooj.exercise2.tehtava3; + +import java.util.Arrays; + +/* + mergeSort-rutiini toteuttaa lomituslajittelun, missä järjestämätön + taulukko pilkotaan puolivälistään kahteen pienempään taulukkoon, + jotka vuorostaan pilkotaan pienempiin n kertaa kunnes jokaiseen taulukkoon + jää jäljelle yksi alkio. Tämän jälkeen alkiot järjestetään saman menettelytavan + mukaan aina kaksinkertaiseen taulukkoon ja alkioiden kesken toteutetaan niiden + lukuarvoon perustuva lajittelu. + + mergeSort-metodi toteuttaa ensin parametrinä saamansa taulukon jakamisen pienempiin + taulukkoihin ja lopuksi kutsuu merge-metodia, joka yhdistää pilkotut taulukot yhdeksi taulukoksi + järjestäen pilkottujen taulukoiden alkiot suuruusjärjestykseen ottamalla aina saman indeksin kahdesta + eri taulukosta ja asettaen ne uuteen taulukkoon siinä järjestyksessä, kumpi on pienempi + +mergeSort-metodin osalta voisi selvittää seuraava: + taulukosta poimitaan kaksi satunnaista indeksiä. Onhan jokaisen indeksin kanssa seuraava väite tosi: + (jos indeksi(1) > indeksi(2) -> luku(1) > luku(2); jos ei, luku(1) <= luku(2)); + + merge-,metodin osalta voisi selvittää + (1) onhan palautetussa taulukossa yhtä monta alkiota kuin annetussa taulukossa + (2) käsitellään kahta eri yhdistettyä taulukkoa keskenään vertaillen saman indeksin saaneita lukuja taulukoissa: + (jos taulukko1.arvoIndeksissä(1) < taulukko2.arvoIndeksissä(1) -> yhdistettyTaulukko.alkionIndeksi(taulukko1.arvoIndeksissä(1)) <= taulukko2.arvoIndeksissä(1); + jos ei, yhdistettyTaulukko.alkionIndeksi(taulukko1.arvoIndeksissä(1)) > taulukko2.arvoIndeksissä(1)) + */ + +public class Sorting { + + public static void mergeSort(int[] a) { + int n = a.length; + if (n < 2) { + return; + } + int mid = n / 2; + int[] l = new int[mid]; + int[] r = new int[n - mid]; + + for (int i = 0; i < mid; i++) { + l[i] = a[i]; + } + for (int i = mid; i < n; i++) { + r[i - mid] = a[i]; + } + + mergeSort(l); + mergeSort(r); + + merge(a, l, r, mid, n - mid); + } + + public static void merge(int[] a, int[] l, int[] r, int left, int right) { + int i = 0, j = 0, k = 0; + while (i < left && j < right) { + if (l[i] <= r[j]) { + a[k++] = l[i++]; + } + else { + a[k++] = r[j++]; + } + } + while (i < left) { + a[k++] = l[i++]; + } + while (j < right) { + a[k++] = r[j++]; + } + } +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Kayttoliittyma.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Kayttoliittyma.java new file mode 100644 index 0000000000000000000000000000000000000000..58e1000fa13620120ea4c62438d0085b6e20b9aa --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Kayttoliittyma.java @@ -0,0 +1,112 @@ +package fi.utu.tech.ooj.exercise2.tehtava4; + +import java.util.HashMap; +import java.util.Scanner; + +public class Kayttoliittyma { + public Kayttoliittyma() { + Scanner scanner = new Scanner(System.in); + + Ottelu ottelu = new Ottelu(); + + String input = ""; + + while (true) { + System.out.println("Haluatko lisätä uuden urheilulajin otteluun? Valitse K (kyllä) / E (ei)"); + + input = scanner.nextLine(); + + if (input.contains("K")) { + String lajinNimi = ""; + int enimmaispisteet = 100; + boolean laskevaPisteytys = true; + + System.out.println("Kirjoita lajin nimi ja paina ENTER:"); + input = scanner.nextLine(); + lajinNimi = input; + + System.out.println("Kirjoita lajista saatavat enimmäispisteet ja paina ENTER:"); + input = scanner.nextLine(); + enimmaispisteet = Integer.valueOf(input); + + System.out.println("Onko pisteytys laskeva? Laskeva tarkoittaa sitä, että suurempi tulos on parempi. Valitse K (Kyllä) / E (Ei"); + input = scanner.nextLine(); + + laskevaPisteytys = (input.equals("K")); + + Urheilulaji urheilulaji = new Urheilulaji(lajinNimi, enimmaispisteet, laskevaPisteytys); + ottelu.LisaaUrheilulaji(urheilulaji); + System.out.println(); + System.out.println("Olet lisännyt urheilulajin. Tällä hetkellä lisättyjä lajeja ovat:"); + for (Urheilulaji laji : ottelu.PalautaUrheilulajit()) { + System.out.println(laji.nimi); + } + } else if (input.contains("E")) { + break; + } + } + + while (true) { + System.out.println("Haluatko lisätä uuden tuloksen otteluun? Valitse K (kyllä) / E (ei)"); + + input = scanner.nextLine(); + + if (input.contains("K")) { + String urheilijanNimi = ""; + + System.out.println("Kirjoita urheilijan nimi, jolle lisäät tuloksen ja paina ENTER:"); + input = scanner.nextLine(); + urheilijanNimi = input; + + HashMap<Integer, Urheilulaji> numerotJaLajit = new HashMap<>(); + + int i = 1; + for (Urheilulaji urheilulaji : ottelu.PalautaUrheilulajit()) { + numerotJaLajit.put(i, urheilulaji); + i++; + } + + for (Integer lajinumero : numerotJaLajit.keySet()) { + System.out.println(lajinumero + ": " + numerotJaLajit.get(lajinumero)); + } + + System.out.println("Valitse lajin numero, jolle lisäät tuloksen:"); + + int lajinumero = Integer.valueOf(scanner.nextLine()); + + System.out.println("Valitsit lajin: " + numerotJaLajit.get(lajinumero)); + + System.out.println("Kirjoita urheilijan tulosluku. Tarvittaessa käytä erottimena pistettä:"); + Double tulos = Double.valueOf(scanner.nextLine().trim()); + + System.out.println("Syötit tuloksen: " + tulos); + + ottelu.LisaaTulos(urheilijanNimi, tulos, numerotJaLajit.get(lajinumero).PalautaNimi()); + + System.out.println("Olet lisännyt tuloksen. Tällä hetkellä järjestelmään lisättyjä urheilijoita ovat:"); + + for(Urheilija urheilija : ottelu.PalautaUrheilijat()) { + System.out.println(urheilija.PalautaNimi()); + } + } else if (input.contains("E")) { + break; + } + } + + System.out.println("OTTELUN TULOKSET:"); + + for (Urheilulaji urheilulaji : ottelu.PalautaUrheilulajit()) { + urheilulaji.TulostaTulokset(); + } + + System.out.println("LOPULLINEN PISTEYTYS:"); + + HashMap<Urheilija, Double> pisteytys = ottelu.PisteytaUrheilijat(); + + for(Urheilija urheilija : pisteytys.keySet()) { + System.out.println(urheilija.PalautaNimi() + ", pisteet " + pisteytys.get(urheilija)); + } + + System.out.println("OTTELU ON OHI"); + } +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Ottelu.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Ottelu.java new file mode 100644 index 0000000000000000000000000000000000000000..857d35e443e253960cc287cad6fd662a4ec22af5 --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Ottelu.java @@ -0,0 +1,97 @@ +package fi.utu.tech.ooj.exercise2.tehtava4; + +import java.util.*; + +public class Ottelu { + private HashMap<String, Urheilulaji> urheilulajit; + private HashMap<String, Urheilija> lisatytUrheilijat; + + public Ottelu() { + urheilulajit = new HashMap<>(); + lisatytUrheilijat = new HashMap<>(); + } + + public Ottelu(Urheilulaji[] urheilulajit) { + this.urheilulajit = new HashMap<>(); + for(Urheilulaji urheilulaji : urheilulajit) { + this.urheilulajit.put(urheilulaji.PalautaNimi(), urheilulaji); + } + } + + public Ottelu(ArrayList<Urheilulaji> urheilulajit) { + this.urheilulajit = new HashMap<>(); + for(Urheilulaji urheilulaji : urheilulajit) { + this.urheilulajit.put(urheilulaji.PalautaNimi(), urheilulaji); + } + } + + public boolean LisaaUrheilulaji(Urheilulaji lisattavaLaji) { + if (!urheilulajit.containsKey(lisattavaLaji)) { + urheilulajit.put(lisattavaLaji.PalautaNimi(), lisattavaLaji); + return true; + } + return false; + } + + public ArrayList<Urheilulaji> PalautaUrheilulajit() { + ArrayList<Urheilulaji> palautettavaLista = new ArrayList<>(); + + for (Urheilulaji urheilulaji : urheilulajit.values()) { + palautettavaLista.add(urheilulaji); + } + + return palautettavaLista; + } + + public ArrayList<Urheilija> PalautaUrheilijat() { + ArrayList<Urheilija> urheilijat = new ArrayList<>(); + for (Urheilija urheilija : lisatytUrheilijat.values()) { + urheilijat.add(urheilija); + } + + return urheilijat; + } + + public boolean LisaaTulos(Urheilija urheilija, double tulos, Urheilulaji urheilulaji) { + if (urheilulajit.containsKey(urheilulaji.PalautaNimi())) { + if (lisatytUrheilijat.containsKey(urheilija.PalautaNimi())) { + urheilija = lisatytUrheilijat.get(urheilija.PalautaNimi()); + } + urheilulaji.LisaaTulos(urheilija, tulos); + return true; + } else { + return false; + } + } + + public void LisaaTulos(String urheilijanNimi, double tulos, String urheilulajinNimi) { + if (urheilulajit.containsKey(urheilulajinNimi)) { + Urheilija loydettyUrheilija = null; + if (lisatytUrheilijat.containsKey(urheilijanNimi)) { + loydettyUrheilija = lisatytUrheilijat.get(urheilijanNimi); + urheilulajit.get(urheilulajinNimi).LisaaTulos(loydettyUrheilija, tulos); + } else { + Urheilija urheilija = new Urheilija(urheilijanNimi); + lisatytUrheilijat.put(urheilijanNimi, urheilija); + urheilulajit.get(urheilulajinNimi).LisaaTulos(urheilija, tulos); + } + } + } + + public HashMap<Urheilija, Double> PisteytaUrheilijat() { + HashMap<Urheilija, Double> pisteytetytUrheilijat = new HashMap<>(); + for(Urheilulaji urheilulaji : urheilulajit.values()) { + HashMap<Urheilija, Double> lajikohtaisetPisteet = urheilulaji.PisteytaUrheilijat(); + + for(Urheilija urheilija : lajikohtaisetPisteet.keySet()) { + if (!pisteytetytUrheilijat.containsKey(urheilija)) { + pisteytetytUrheilijat.put(urheilija, 0.0); + } + + pisteytetytUrheilijat.put(urheilija, pisteytetytUrheilijat.get(urheilija) + lajikohtaisetPisteet.get(urheilija)); + } + } + + return pisteytetytUrheilijat; + } +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Tulostaulukko.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Tulostaulukko.java new file mode 100644 index 0000000000000000000000000000000000000000..258440f321a772dac8bf2ff8104b937445f59aed --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Tulostaulukko.java @@ -0,0 +1,167 @@ +package fi.utu.tech.ooj.exercise2.tehtava4; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Dictionary; +import java.util.HashMap; + +public class Tulostaulukko { + private HashMap<Urheilija, ArrayList<Double>> tulokset; + + public Tulostaulukko() { + tulokset = new HashMap<>(); + } + + public ArrayList<Urheilija> PalautaUrheilijat() { + ArrayList<Urheilija> urheilijat = new ArrayList<>(); + + for (Urheilija urheilija : tulokset.keySet()) { + urheilijat.add(urheilija); + } + + return urheilijat; + } + + public Urheilija PalautaUrheilijaNimella(String nimi) { + for(Urheilija urheilija : tulokset.keySet()) { + if (urheilija.PalautaNimi().equals(nimi)) { + return urheilija; + } + } + return null; + } + + public void LisaaTulos(Urheilija urheilija, double tulos) { + if (!tulokset.containsKey(urheilija)) { + tulokset.put(urheilija, new ArrayList<>()); + } + + tulokset.get(urheilija).add(tulos); + } + + public double PalautaSuurinTulos(Urheilija urheilija) { + double suurinTulos = Double.MIN_VALUE; + + if (tulokset.containsKey(urheilija)) { + for(Double tulos : tulokset.get(urheilija)) { + if (tulos > suurinTulos) { + suurinTulos = tulos; + } + } + return suurinTulos; + } + return -1; + } + + public HashMap<Urheilija, Double> PalautaUrheilijoidenSuurimmatTulokset(Urheilija[] urheilijat) { + HashMap<Urheilija, Double> suurimmatTulokset = new HashMap<>(); + for(Urheilija urheilija : urheilijat) { + double suurinTulos = PalautaSuurinTulos(urheilija); + if (suurinTulos != -1) { + suurimmatTulokset.put(urheilija, suurinTulos); + } + } + + return suurimmatTulokset; + } + + public HashMap<Urheilija, Double> PalautaUrheilijoidenSuurimmatTulokset() { + return PalautaUrheilijoidenSuurimmatTulokset(Utils.MuunnaObjektitaulukkoUrheilijataulukoksi(tulokset.keySet().toArray())); + } + + public HashMap<Urheilija, Double> PalautaUrheilijoidenSuurimmatTulokset(ArrayList<Urheilija> urheilijat) { + return PalautaUrheilijoidenSuurimmatTulokset((Utils.MuunnaObjektitaulukkoUrheilijataulukoksi(tulokset.keySet().toArray()))); + } + + public ArrayList<Double> PalautaTulokset(Urheilija urheilija) { + if (tulokset.containsKey(urheilija)) { + return tulokset.get(urheilija); + } else { + return null; + } + } + + public Urheilija PalautaUrheilijaSuurimmallaTuloksella() { + return PalautaUrheilijaSuurimmallaTuloksella(Utils.MuunnaObjektitaulukkoUrheilijataulukoksi(tulokset.keySet().toArray())); + } + + public Urheilija PalautaUrheilijaSuurimmallaTuloksella(Urheilija[] urheilijat) { + HashMap<Urheilija, Double> suurimmatTulokset = PalautaUrheilijoidenSuurimmatTulokset(urheilijat); + + Urheilija kaikistaSuurinUrheilija = null; + double kaikistaSuurinTulos = Double.MIN_VALUE; + + for (Urheilija urheilija : suurimmatTulokset.keySet()) { + if (suurimmatTulokset.get(urheilija) > kaikistaSuurinTulos) { + kaikistaSuurinUrheilija = urheilija; + kaikistaSuurinTulos = suurimmatTulokset.get(urheilija); + } + } + + return kaikistaSuurinUrheilija; + } + + public Urheilija PalautaUrheilijaSuurimmallaTuloksella(ArrayList<Urheilija> urheilijat) { + return PalautaUrheilijaSuurimmallaTuloksella(Utils.MuunnaObjektitaulukkoUrheilijataulukoksi(tulokset.keySet().toArray())); + } + + public double PalautaPieninTulos(Urheilija urheilija) { + double pieninTulos = Double.MAX_VALUE; + + if (tulokset.containsKey(urheilija)) { + for(Double tulos : tulokset.get(urheilija)) { + if (tulos < pieninTulos) { + pieninTulos = tulos; + } + } + return pieninTulos; + } + return -1; + } + + public HashMap<Urheilija, Double> PalautaUrheilijoidenPienimmatTulokset() { + return PalautaUrheilijoidenPienimmatTulokset(Utils.MuunnaObjektitaulukkoUrheilijataulukoksi(tulokset.keySet().toArray())); + } + + public HashMap<Urheilija, Double> PalautaUrheilijoidenPienimmatTulokset(Urheilija[] urheilijat) { + HashMap<Urheilija, Double> pienimmatTulokset = new HashMap<>(); + for(Urheilija urheilija : urheilijat) { + double pieninTulos = PalautaPieninTulos(urheilija); + + if (pieninTulos != -1) { + pienimmatTulokset.put(urheilija, pieninTulos); + } + } + + return pienimmatTulokset; + } + + public HashMap<Urheilija, Double> PalautaUrheilijoidenPienimmatTulokset(ArrayList<Urheilija> urheilijat) { + return PalautaUrheilijoidenPienimmatTulokset(Utils.MuunnaObjektitaulukkoUrheilijataulukoksi(tulokset.keySet().toArray())); + } + + public Urheilija PalautaUrheilijaPienimmallaTuloksella() { + return PalautaUrheilijaPienimmallaTuloksella(Utils.MuunnaObjektitaulukkoUrheilijataulukoksi(tulokset.keySet().toArray())); + } + + public Urheilija PalautaUrheilijaPienimmallaTuloksella(Urheilija[] urheilijat) { + HashMap<Urheilija, Double> pienimmatTulokset = PalautaUrheilijoidenSuurimmatTulokset(urheilijat); + + Urheilija kaikistaPieninUrheilija = null; + double kaikistaPieninTulos = Double.MAX_VALUE; + + for (Urheilija urheilija : pienimmatTulokset.keySet()) { + if (pienimmatTulokset.get(urheilija) < kaikistaPieninTulos) { + kaikistaPieninUrheilija = urheilija; + kaikistaPieninTulos = pienimmatTulokset.get(urheilija); + } + } + + return kaikistaPieninUrheilija; + } + + public Urheilija PalautaUrheilijaPienimmallaTuloksella(ArrayList<Urheilija> urheilijat) { + return PalautaUrheilijaPienimmallaTuloksella(Utils.MuunnaObjektitaulukkoUrheilijataulukoksi(tulokset.keySet().toArray())); + } +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Urheilija.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Urheilija.java new file mode 100644 index 0000000000000000000000000000000000000000..9d5b6e5b4ed41fc2c400d4149ab4b9d84a02899b --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Urheilija.java @@ -0,0 +1,18 @@ +package fi.utu.tech.ooj.exercise2.tehtava4; + +public class Urheilija { + private String nimi; + + public Urheilija(String nimi) { + this.nimi = nimi; + } + + public String PalautaNimi() { + return nimi; + } + + @Override + public String toString() { + return nimi; + } +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Urheilulaji.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Urheilulaji.java new file mode 100644 index 0000000000000000000000000000000000000000..3d34022b54b01ed136f5c1c5ed3e601223d1cb73 --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Urheilulaji.java @@ -0,0 +1,123 @@ +package fi.utu.tech.ooj.exercise2.tehtava4; + +import java.util.ArrayList; +import java.util.HashMap; + +public class Urheilulaji { + + protected String nimi; + + protected int enimmaismaaraPisteita; + + protected Boolean laskevaPisteytysjarjestys; + + protected Tulostaulukko tulostaulukko; + + public Urheilulaji(String nimi) { + this.nimi = nimi; + this.tulostaulukko = new Tulostaulukko(); + this.enimmaismaaraPisteita = 100; + this.laskevaPisteytysjarjestys = true; + } + + public Urheilulaji(String nimi, int enimmaismaaraPisteita, Boolean laskevaPisteytysjarjestys) { + this.nimi = nimi; + this.tulostaulukko = new Tulostaulukko(); + this.enimmaismaaraPisteita = enimmaismaaraPisteita; + this.laskevaPisteytysjarjestys = laskevaPisteytysjarjestys; + } + + public String PalautaNimi() { + return nimi; + } + + public int PalautaEnimmaispisteet() { + return enimmaismaaraPisteita; + } + + public boolean OnkoPisteytysjarjestysLaskeva() { + return laskevaPisteytysjarjestys; + } + + public ArrayList<Urheilija> PalautaUrheilijat() { + return tulostaulukko.PalautaUrheilijat(); + } + + public void LisaaTulos(Urheilija urheilija, Double tulos) { + tulostaulukko.LisaaTulos(urheilija, tulos); + } + + public boolean LisaaTulos(String nimi, Double tulos) { + Urheilija urheilija = tulostaulukko.PalautaUrheilijaNimella(nimi); + + if (urheilija != null) { + tulostaulukko.LisaaTulos(urheilija, tulos); + return true; + } else { + return false; + } + } + + public HashMap<Urheilija, Double> PisteytaUrheilijat() { + HashMap<Urheilija, Double> tulokset = new HashMap<>(); + + if (laskevaPisteytysjarjestys) { + tulokset = tulostaulukko.PalautaUrheilijoidenSuurimmatTulokset(); + } else { + tulokset = tulostaulukko.PalautaUrheilijoidenPienimmatTulokset(); + } + + HashMap<Object, Double> parametritaulukko = new HashMap<>(); + + for(Urheilija urheilija : tulokset.keySet()) { + parametritaulukko.put(urheilija, tulokset.get(urheilija)); + } + + ArrayList<Object> urheilijatJarjestyksessa = Utils.PalautaHashMapinObjektitJarjestyksessa(parametritaulukko, laskevaPisteytysjarjestys); + + HashMap<Urheilija, Double> pistetaulukko = new HashMap<>(); + + int i = 0; + double n = parametritaulukko.size(); + for (Object objekti : urheilijatJarjestyksessa) { + double pisteet = enimmaismaaraPisteita - ((i / n) * enimmaismaaraPisteita); + pistetaulukko.put((Urheilija) objekti, pisteet); + i++; + } + + return pistetaulukko; + } + + public void TulostaTulokset() { + System.out.println("Tulokset lajista " + PalautaNimi() + "\n"); + + HashMap<Urheilija, Double> pisteytetytUrheilijat = PisteytaUrheilijat(); + + if (laskevaPisteytysjarjestys) { + System.out.println("VOITTAJA: " + tulostaulukko.PalautaUrheilijaSuurimmallaTuloksella().PalautaNimi()); + } else { + System.out.println("VOITTAJA: " + tulostaulukko.PalautaUrheilijaPienimmallaTuloksella().PalautaNimi()); + } + + System.out.println(); + + if (laskevaPisteytysjarjestys) { + int i = 1; + for(Urheilija urheilija : pisteytetytUrheilijat.keySet()) { + System.out.println(i + ": " + urheilija.PalautaNimi() + ", tulos: " + tulostaulukko.PalautaSuurinTulos(urheilija) + ", pisteet: " + pisteytetytUrheilijat.get(urheilija)); + i++; + } + } else { + int i = 1; + for(Urheilija urheilija : pisteytetytUrheilijat.keySet()) { + System.out.println(i + ": " + urheilija.PalautaNimi() + ", tulos: " + tulostaulukko.PalautaPieninTulos(urheilija) + ", pisteet: " + pisteytetytUrheilijat.get(urheilija)); + i++; + } + } + } + + @Override + public String toString() { + return nimi; + } +} diff --git a/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Utils.java b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Utils.java new file mode 100644 index 0000000000000000000000000000000000000000..a4bf380884ed8563174f7b479b9373abfad0e22a --- /dev/null +++ b/src/main/java/fi/utu/tech/ooj/exercise2/tehtava4/Utils.java @@ -0,0 +1,57 @@ +package fi.utu.tech.ooj.exercise2.tehtava4; + +import java.util.*; + +public class Utils { + public static ArrayList<Object> PalautaHashMapinObjektitJarjestyksessa(HashMap<Object, Double> objektit, Boolean laskevaJarjestys) { + Object[] a = objektit.entrySet().toArray(); + + Arrays.sort(a, new Comparator() { + public int compare(Object o1, Object o2) { + return ((Map.Entry<Object, Double>) o2).getValue() + .compareTo(((Map.Entry<Object, Double>) o1).getValue()); + } + }); + + ArrayList<Object> palautettavaLista = new ArrayList<>(); + + for (Object e : a) { + palautettavaLista.add(((Map.Entry<Object, Integer>) e).getKey()); + } + + if (laskevaJarjestys) { + return palautettavaLista; + } else { + ArrayList<Object> uusiLista = new ArrayList<Object>(); + + for(Object objekti1 : palautettavaLista) { + Object pieninObjekti = null; + Double pieninArvo = Double.MAX_VALUE; + for(Object objekti2 : palautettavaLista) { + if (!uusiLista.contains(objekti2)) { + if (objektit.get(objekti2) < pieninArvo) { + pieninArvo = objektit.get(objekti2); + pieninObjekti = objekti2; + } + } + } + + if (pieninObjekti != null) { + uusiLista.add(pieninObjekti); + } + } + + return uusiLista; + } + } + + public static Urheilija[] MuunnaObjektitaulukkoUrheilijataulukoksi(Object[] objectArray) { + Urheilija[] urheilijaArray = new Urheilija[objectArray.length]; + + for (int i = 0; i < objectArray.length; i++) { + urheilijaArray[i] = (Urheilija) objectArray[i]; + } + + return urheilijaArray; + } +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index a28d3fda3d0ac52988b5dd271cc9f0572a970026..b08c15eeed19e3eca9138f177e8e324fc47c4f20 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -2,4 +2,14 @@ module fi.utu.tech.ooj.exercise2 { exports fi.utu.tech.ooj.exercise2; opens fi.utu.tech.ooj.exercise2; + exports fi.utu.tech.ooj.exercise2.tehtava2.tietoyhteys; + opens fi.utu.tech.ooj.exercise2.tehtava2.tietoyhteys; + exports fi.utu.tech.ooj.exercise2.tehtava1; + opens fi.utu.tech.ooj.exercise2.tehtava1; + exports fi.utu.tech.ooj.exercise2.tehtava2; + opens fi.utu.tech.ooj.exercise2.tehtava2; + exports fi.utu.tech.ooj.exercise2.tehtava3; + opens fi.utu.tech.ooj.exercise2.tehtava3; + exports fi.utu.tech.ooj.exercise2.tehtava4; + opens fi.utu.tech.ooj.exercise2.tehtava4; } diff --git a/src/test/java/fi/utu/tech/ooj/exercise2/ActivationTest.java b/src/test/java/fi/utu/tech/ooj/exercise2/ActivationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..341844c137fcfb620fe79baac9e4aa7d24858b5b --- /dev/null +++ b/src/test/java/fi/utu/tech/ooj/exercise2/ActivationTest.java @@ -0,0 +1,56 @@ +package fi.utu.tech.ooj.exercise2; + +import fi.utu.tech.ooj.exercise2.tehtava3.Activation; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Random; + +/* + Jotta metodi toimisi kuin parametrisen ReLU-funktion kuuluu, sen tulee + palauttaa x, jos x > 0 ja muussa tapauksessa parametri a * x. + Tätä voidaan testata seuraavilla testeillä + + (1) Palauttaako funktio x:n, kun x = 1? + (2) Palauttaako funtio a * x, kun x on 0 tai negatiivinen luku ja + a satunnaisluku välillä (0.01-1)? + + Testien valossa METODI VAIKUTTAISI TOIMIVAN MÄÄRITTELYNSÄ MUKAAN! + */ +class ActivationTest { + + Random random = new Random(); + + @Test + void testaaParametricReLU() { + float x = 0; + float a = 0; + parametricReLU(x, a); + } + + @Test + void parametricReLU(float x, float a) { + float result = 0; + + x = 0; + a = random.nextFloat(0,1); + + result = Activation.parametricReLU(x, a); + + Assertions.assertEquals(result, x * a); + + x = 1; + + result = Activation.parametricReLU(x, a); + + Assertions.assertEquals(result, x); + + for (int i = 0; i < 10; i++) { + x = random.nextFloat(-10,0); + a = random.nextFloat(0,1); + result = Activation.parametricReLU(x,a); + + Assertions.assertEquals(result, x * a); + } + } +} \ No newline at end of file diff --git a/src/test/java/fi/utu/tech/ooj/exercise2/CarTest.java b/src/test/java/fi/utu/tech/ooj/exercise2/CarTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7d72e33454423753a840ec95fd3c338ac9f30aa1 --- /dev/null +++ b/src/test/java/fi/utu/tech/ooj/exercise2/CarTest.java @@ -0,0 +1,216 @@ +package fi.utu.tech.ooj.exercise2; + +import fi.utu.tech.ooj.exercise2.tehtava3.Car; +import org.junit.jupiter.api.Test; + +import java.time.Year; + +import static org.junit.jupiter.api.Assertions.*; + +/* + Luokka Car EI TOIMI TÄYSIN LUOKKAINVARIANTTINSA MUKAAN. + Jos asetan setRegistered-metodissa auton rekisteröinnin arvoksi + arvon "tosi", ei luokalle muodostu omaa, välilyönnit poislukien + vähintään 6-merkkistä rekisteritunnusta. Luokassa voi siis + todellisuudessa olla rekisteröitynä auto, jolla ei ole rekisteri- + tunnusta. Tämä ei ole luokkainvariantin mukaista, jossa + määritellään: + ( isRegistered == true && registerNumber.trim.length >=6 ) + + Muilta osin yhdeksän kymmenestä testistä menee läpi. + */ + +class CarTest { + + @Test + void getManufacturer() { + } + + /* + Seuraava testimetodi testaa seuraavat asiat: + (1) Jos auton valmistajaksi asetetaan tyhjä arvo (null), auton valmistaja ei ole null + (2) Jos auton valmistajaksi asetetaan luokkainvariantissa määriteltyä + lyhyempi lyhyt merkkijono "W", auton valmistaja ei ole "W" + (3) Jos auton valmistajaksi asetetaan "BMW", auton valmistaja on "BMW" + + Virheellisistä parametreistä johtuvat virhetilanteet ohitetaan virhekäsittelynä, sillä + silloin testi onnistui. + */ + + @Test + void setManufacturer() { + Car car = new Car("Testi", "Testi", 1950); + try { + car.setManufacturer(null); + assertNotEquals(null, car.getManufacturer()); + } catch (IllegalArgumentException e) { + } + + try { + car.setManufacturer("W"); + assertNotEquals("W", car.getManufacturer()); + } catch (IllegalArgumentException e) { + } + + try { + car.setManufacturer("BMW"); + assertEquals("BMW", car.getManufacturer()); + } catch (IllegalArgumentException e) { + } + } + + @Test + void getModel() { + } + + /* + Seuraava testimetodi testaa seuraavat asiat: + (1) Jos auton malliksi malliksi tyhjä arvo (null), auton malli ei ole null + (2) Jos auton malliksi asetetaan luokkainvariantissa määritettyä lyhyempi + merkkijono "A", auton malli ei ole "A" + (3) Jos auton malliksi asetetaan "A1", auton malli on "A1" + + Virheellisistä parametreistä johtuvat virhetilanteet ohitetaan virhekäsittelynä, sillä + silloin testi onnistui. + */ + @Test + void setModel() { + Car car = new Car("Testi", "Testi", 1950); + try { + car.setModel(null); + assertNotEquals(null, car.getModel()); + } catch (IllegalArgumentException e) { + } + + try { + car.setModel("A"); + assertNotEquals("A", car.getModel()); + } catch (IllegalArgumentException e) { + } + + try { + car.setModel("A1"); + assertEquals("A1", car.getModel()); + } catch (IllegalArgumentException e) { + } + } + + @Test + void getModelYear() { + } + + /* + Seuraava testimetodi testaa seuraavat asiat: + (1) Jos auton valmistusvuodeksi asetetaan tyhjä arvo (null), auton valmistusvuosi ei ole null + (2) Jos auton valmistusvuodeksi asetetaan luokkainvariantissa määritetyn alueen ulkopuolelta + vuosi 1800, auton valmistuvuosi ei ole 1800 + (3) Jos auton valmistusvuodeksi asetaan luokkainvariantissa määritetyn alueen ulkopuolelta + vuosi (tämä vuosi) + 1, auton valmistusvuosi ei ole (tämä vuosi) + 1 + + Virheellisistä parametreistä johtuvat virhetilanteet ohitetaan virhekäsittelynä, sillä + silloin testi onnistui. + */ + @Test + void setModelYear() { + Car car = new Car("Testi", "Testi", 1950); + try { + car.setModelYear(null); + assertNotEquals(null, car.getModelYear()); + } catch (IllegalArgumentException e) { + } + + try { + car.setModelYear(1800); + assertNotEquals(1800, car.getModelYear()); + } catch (IllegalArgumentException e) { + } + + try { + car.setModelYear(Year.now().getValue() + 1); + assertNotEquals(Year.now().getValue() + 1, car.getModelYear()); + } catch (IllegalArgumentException e) { + } + } + + @Test + void getRegistered() { + } + + /* + Seuraava testimetodi testaa seuraavat asiat: + (1) Jos auton rekisteröinnin arvoksi asetetaan tyhjä arvo (null), auton rekisteröinnin arvo ei ole null + (2) Jos auton rekisteröinnin arvoksi asetaan tosi arvo, auton rekisterinumerossa on oltava + vähintään 6 merkkiä poislukien välilyönnit + (3) Jos auton rekisteröinnin arvoksi asetetaan epätosi arvo, auton rekisterinumeron on oltava tyhjä merkkijono + + Virheellisistä parametreistä johtuvat virhetilanteet ohitetaan virhekäsittelynä, sillä + silloin testi onnistui. + */ + @Test + void setRegistered() { + Car car = new Car("Testi", "Testi", 1950); + try { + car.setRegistered(null); + assertNotEquals(null, car.getRegistered()); + } catch (IllegalArgumentException e) { + } + + try { + car.setRegistered(true); + assertTrue(car.getRegisterNumber().trim().length() >= 6); + } catch (IllegalArgumentException e) { + } + + try { + car.setRegistered(false); + assertTrue(car.getRegisterNumber().isBlank()); + } catch (IllegalArgumentException e) { + } + } + + @Test + void getRegisterNumber() { + } + + /* + Seuraava testimetodi testaa seuraavat asiat: + (1) Jos auton rekisterinumeron arvoksi asetetaan tyhjä arvo (null), auton rekisterinumeron arvo ei ole null + (2) Jos auton rekisterinumeroksi asetaan luokkainvariantissa sallitun kokoinen merkkijono, jonka pituus + on 11 merkkiä, auton rekisteröinnin arvoksi asetetaan tosi + (3) Jos auton rekisterinumeroksi asetetaan luokkainvariantissa määritellyn vastainen merkkijono, jonka pituus + on 5 merkkiä, JOKO auton rekisteröinnin arvo on epätosi TAI auton rekisterinumero on muutettu muotoon, jossa + sen pituus on luokkainvariantissa määritellyn mukainen >= 6 merkkiä, poislukien välilyönnit + (4) Jos auton rekisterinumeroksi asetetaan tyhjä merkkijono, auton rekisteröinnin arvoksi asetetaan + epätosi arvo + + Virheellisistä parametreistä johtuvat virhetilanteet ohitetaan virhekäsittelynä, sillä + silloin testi onnistui. + */ + @Test + void setRegisterNumber() { + Car car = new Car("Testi", "Testi", 1950); + try { + car.setRegisterNumber(null); + assertNotEquals(null, car.getRegisterNumber()); + } catch (IllegalArgumentException e) { + } + + try { + car.setRegisterNumber("BMW12345678"); + assertTrue(car.getRegistered()); + } catch (IllegalArgumentException e) { + } + + try { + car.setRegisterNumber("BMW12"); + assertTrue(!car.getRegistered() || car.getRegisterNumber().trim().length() >= 6); + } catch (IllegalArgumentException e) { + } + + try { + car.setRegisterNumber(""); + assertFalse(car.getRegistered()); + } catch (IllegalArgumentException e) { + } + } +} \ No newline at end of file diff --git a/src/test/java/fi/utu/tech/ooj/exercise2/MergeSortTest.java b/src/test/java/fi/utu/tech/ooj/exercise2/MergeSortTest.java deleted file mode 100644 index eb52e35dd16f8d226071e22aa10c700f57000f43..0000000000000000000000000000000000000000 --- a/src/test/java/fi/utu/tech/ooj/exercise2/MergeSortTest.java +++ /dev/null @@ -1,5 +0,0 @@ -package fi.utu.tech.ooj.exercise2; - -public class MergeSortTest { - -} diff --git a/src/test/java/fi/utu/tech/ooj/exercise2/PalindromeTest.java b/src/test/java/fi/utu/tech/ooj/exercise2/PalindromeTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0df9c20e4aa83b572b1811a131b9ab5b6469e393 --- /dev/null +++ b/src/test/java/fi/utu/tech/ooj/exercise2/PalindromeTest.java @@ -0,0 +1,43 @@ +package fi.utu.tech.ooj.exercise2; + +import fi.utu.tech.ooj.exercise2.tehtava3.Palindrome; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/* + Alla olevat metodit testaavat Palindrome-luokan + convertToPalindrome-metodin palauttamien merkkijonojen + osalta niiden palindromisuuden. Toisin sanoen, ovatko merkkijonon + merkit n ja (merkkijonon pituus) - n merkit samat. Jos ovat, testi + menee läpi, jos eivät, testi ei mene läpi. + + Merkkijonot eivät vaikuta testin perusteella olevan liittymäkohdiltaan palindromisia, + joten METODI EI TOIMI OIKEIN. + */ +class PalindromeTest { + + + @Test + void testaaConvertToPalindrome() { + String merkkijono = "Tämä on testimerkkijono"; + convertToPalindrome(merkkijono); + } + + @Test + void convertToPalindrome(String str) { + String palindromi = Palindrome.convertToPalindrome(str); + int palindrominKeskiosa = (palindromi.length() / 2); + System.out.println(palindromi); + int downIndex = 0; + int upIndex = palindromi.length() - 1; + + for (int x = 0; x < palindrominKeskiosa + 1; x++) { + char downCharacter = palindromi.charAt(downIndex); + char upCharacter = palindromi.charAt(upIndex); + Assertions.assertEquals(downCharacter, upCharacter); + + downIndex++; + upIndex--; + } + } +} \ No newline at end of file diff --git a/src/test/java/fi/utu/tech/ooj/exercise2/SortingTest.java b/src/test/java/fi/utu/tech/ooj/exercise2/SortingTest.java new file mode 100644 index 0000000000000000000000000000000000000000..045816f6e708ab222a950e26c9ff24e2bccacee6 --- /dev/null +++ b/src/test/java/fi/utu/tech/ooj/exercise2/SortingTest.java @@ -0,0 +1,128 @@ +package fi.utu.tech.ooj.exercise2; + +import fi.utu.tech.ooj.exercise2.tehtava3.Sorting; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Random; + +/* mergeSort-metodin osalta voisi selvittää seuraava: + taulukosta poimitaan kaksi satunnaista indeksiä. Onhan jokaisen indeksin kanssa seuraava väite tosi: + (jos indeksi(1) > indeksi(2) -> luku(1) > luku(2); jos ei, luku(1) <= luku(2)); + + merge-,metodin osalta voisi selvittää + (1) onhan palautetussa taulukossa yhtä monta alkiota kuin annetussa taulukossa + (2) käsitellään kahta eri yhdistettyä taulukkoa keskenään vertaillen saman indeksin saaneita lukuja taulukoissa: + (jos taulukko1.arvoIndeksissä(1) < taulukko2.arvoIndeksissä(1) -> yhdistettyTaulukko.alkionIndeksi(taulukko1.arvoIndeksissä(1)) <= taulukko2.arvoIndeksissä(1); + jos ei, yhdistettyTaulukko.alkionIndeksi(taulukko1.arvoIndeksissä(1)) > taulukko2.arvoIndeksissä(1)) + + Testien perusteella LAJITTELU VAIKUTTAA TOIMIVAN OIKEIN! + */ +class SortingTest { + + Random random = new Random(); + + @Test + void testaaMergeSort() { + int taulukonKoko = random.nextInt(1,50); + int[] taulukko = new int[taulukonKoko]; + + for (int i = 0; i < taulukko.length; i++) { + taulukko[i] = random.nextInt(101) - 50; + } + + mergeSort(taulukko); + } + @Test + void mergeSort(int[] taulukko) { + + Sorting.mergeSort(taulukko); + // valitaan 10 kertaa kaksi satunnaista alkiota + for (int x = 0; x < 10; x++) { + int[][] testiarvot = new int[2][2]; + for (int i = 0; i < 2; i++) { + testiarvot[i][0] = random.nextInt(0, taulukko.length); + testiarvot[i][1] = taulukko[testiarvot[i][0]]; + } + + if (testiarvot[0][0] > testiarvot[1][0]) { + // ensimmäisen indeksi suurempi eli ensimmäisen pitäisi olla suurempi + Assertions.assertTrue(testiarvot[0][1] > testiarvot[1][1]); + } else if (testiarvot[0][0] == testiarvot[1][0]) { + // indeksit samankokoisia eli sama luku! + Assertions.assertTrue(testiarvot[0][1] == testiarvot[1][1]); + } else if (testiarvot[0][0] < testiarvot[1][0]) { + // ensimmäisen indeksi pienempi eli ensimmäisen pitäisi olla pienempi + Assertions.assertTrue(testiarvot[0][1] < testiarvot[1][1]); + } + } + } + + @Test + void testaaMerge() { + int taulukon1Koko = random.nextInt(1,5); + int[] taulukko1 = new int[taulukon1Koko]; + int taulukon2Koko = random.nextInt(1,5); + int[] taulukko2 = new int[taulukon2Koko]; + + int[] yhdistettyTaulukko = new int[taulukon1Koko + taulukon2Koko]; + + for (int i = 0; i < taulukko1.length; i++) { + taulukko1[i] = random.nextInt(101); + yhdistettyTaulukko[i] = taulukko1[i]; + } + + for (int i = 0; i < taulukko2.length; i++) { + taulukko2[i] = random.nextInt(101) - 50; + yhdistettyTaulukko[taulukon1Koko + i] = taulukko2[i]; + } + + merge(yhdistettyTaulukko, taulukko1, taulukko2, taulukon1Koko, yhdistettyTaulukko.length - taulukon1Koko); + } + + /* + (jos taulukko1.arvoIndeksissä(1) < taulukko2.arvoIndeksissä(1) -> yhdistettyTaulukko.alkionIndeksi(taulukko1.arvoIndeksissä(1)) <= yhdistettyTaulukko.alkionIndeksi(taulukko2.arvoIndeksissä(1)); + jos ei, yhdistettyTaulukko.alkionIndeksi(taulukko1.arvoIndeksissä(1)) > taulukko2.arvoIndeksissä(1)) + && (yhdistettyTaulukko.pituusMetodinAlussa() == yhdistettyTaulukko.pituusMetodinLopussa()) + */ + @Test + void merge(int[] a, int[] l, int[] r, int left, int right) { + + int pituusAlussa = a.length; + + Sorting.merge(a, l, r, left, right); + + int lyhyempiPituus = 0; + + if (l.length < r.length) { + lyhyempiPituus = l.length; + } else { + lyhyempiPituus = r.length; + } + + for (int i = 0; i < lyhyempiPituus; i++) { + int vasTaulukonArvo = l[i]; + int oikTaulukonArvo = r[i]; + + if (vasTaulukonArvo < oikTaulukonArvo) { + Assertions.assertTrue(etsiArvonIndeksi(a, vasTaulukonArvo) < etsiArvonIndeksi(a, oikTaulukonArvo)); + } else if (vasTaulukonArvo == oikTaulukonArvo) { + // koodin mukaan tässä asetetaan ensiksi vasemmanpuoleinen arvo, vaikka päätös on mielivaltainen + Assertions.assertTrue(etsiArvonIndeksi(a, vasTaulukonArvo) < etsiArvonIndeksi(a, oikTaulukonArvo)); + } else if (vasTaulukonArvo > oikTaulukonArvo) { + Assertions.assertTrue(etsiArvonIndeksi(a, vasTaulukonArvo) > etsiArvonIndeksi(a, oikTaulukonArvo)); + } + } + + Assertions.assertEquals(a.length, pituusAlussa); + } + + int etsiArvonIndeksi(int[] taulukko, int etsittavaArvo) { + for (int i = 0; i < taulukko.length; i++) { + if (taulukko[i] == etsittavaArvo) { + return i; + } + } + return -1; + } +} \ No newline at end of file diff --git a/src/test/java/fi/utu/tech/ooj/exercise2/tehtava4/KayttoliittymaTest.java b/src/test/java/fi/utu/tech/ooj/exercise2/tehtava4/KayttoliittymaTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2d3d382531c7992d7d7b431601b52a7c64555367 --- /dev/null +++ b/src/test/java/fi/utu/tech/ooj/exercise2/tehtava4/KayttoliittymaTest.java @@ -0,0 +1,10 @@ +package fi.utu.tech.ooj.exercise2.tehtava4; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class KayttoliittymaTest { + + +} \ No newline at end of file diff --git a/src/test/java/fi/utu/tech/ooj/exercise2/tehtava4/UtilsTest.java b/src/test/java/fi/utu/tech/ooj/exercise2/tehtava4/UtilsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2d4e70bff3e89eecc3712ad4ddaee27649b2e12c --- /dev/null +++ b/src/test/java/fi/utu/tech/ooj/exercise2/tehtava4/UtilsTest.java @@ -0,0 +1,24 @@ +package fi.utu.tech.ooj.exercise2.tehtava4; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.*; +class UtilsTest { + + @Test + void jarjestaHashMap() { + HashMap<Object, Double> tulokset = new HashMap<>(); + tulokset.put(new Urheilija("Laura"), 1000.0); + tulokset.put(new Urheilija("Mikko"), 150.0); + tulokset.put(new Urheilija("Bjarne"), 750.0); + + ArrayList<Object> lista = Utils.PalautaHashMapinObjektitJarjestyksessa(tulokset, true); + + for(Object objekti : lista) { + System.out.println(objekti + " " + tulokset.get(objekti)); + } + } +} \ No newline at end of file