Demo 6
Palauta viimeistään ma klo 11:59.
Ajankäyttösi tällä viikolla (0.5 p.)
Työtuntien kirjaamisesta saa 0.5 demopistettä.
Demokerran päätteeksi kirjoita arvio tällä viikolla käyttämästäsi työmäärästä. Laske työmäärään mukaan kaikki tällä viikolla käyttämäsi aika: lähiopetukseen osallistuminen, oppimateriaalin lukeminen, demotehtävien tekeminen, luentovideon katsominen, demojen purkutilaisuuteen osallistuminen (maanantaina) ja niin edelleen. Voit päivittää lukua viikon edetessä, se voi helpottaa arvion tekemistä. Huom! Siis tähän ei laiteta kurssin alusta kaikkia tunteja yhteensä, vaan vain tämän viikon tunnit.
Osaamistavoitteet
Tämän demokerran päätteeksi
- Osaat kirjoittaa funktion esittelyrivin funktiokutsun perusteella
- Osaat käyttää silmukoita ja taulukoita
- Osaat "kulkea" silmukan avulla taulukon läpi
- Muistat, että
double
-lukuja ei voi vertailla luotettavasti==
-operaattorilla
Harjoittelutehtävät
Voit harjoitella tämän demokerran tehtäviin liittyviä asioita täällä.
Testaaminen
Kaikki tehtävät, joissa on Test
-nappi, tulee testata. ComTest testeissä voit käyttää pohjana seuraavaa:
/// <example>
/// <pre name="test">
/// KIRJOITA TESTIT TÄHÄN VÄLIIN
/// </pre>
/// </example>
Muista käyttää double
-tyyppisten arvojen testaamisessa kolmea matomerkkiä (~~~
) yhtäsuuruusmerkkien sijaan. Tarvittaessa voit Comtestien yhteydessä muuttaa testin tarkkuutta seuraavasti:
The default tolerance is by six digits and it can be changed by #TOLERANCE:
/// #TOLERANCE=0.01
/// double d = 0.101;
/// d ~~~ 0.1;
Tehtävä 1*
Tee funktio TeeTaulukko
. Funktio ottaa parametrina kokonaisluvun, ja palauttaa taulukon, jossa on luvut kyseisestä luvusta alaspäin ykköseen saakka.
Esimerkiksi kutsu TeeTaulukko(5)
palauttaisi taulukon [5, 4, 3, 2, 1]
, TeeTaulukko(1)
palauttaisi taulukon [1]
, jne.
Funktio ei saa tulostaa mitään.
Lisää luomaasi taulukkoon alkiot silmukassa. Helpointa on luoda silmukka, joka käy alkiot läpi "vasemmalta oikealle", ts. laskurimuuttuja i
alkaa arvosta 0.
Jos et keksi miten saat alkiot lisättyä laskevassa järjestyksessä, lisää ne aluksi nousevassa järjestyksessä.
Taulukon paikkaan i
sijoitettavan arvon saat pääteltyä taulukon pituudesta sekä laskurimuuttujasta i
. Keksitkö miten? Kirjoita paperille luvut 5...1 ja mieti miten taulukon pituus ja i
-muuttuja liittyvät kuhunkin alkioon.
Arviointi: Tehtävässä on automaattinen arviointi. Voit halutessasi kirjoittaa omia ComTest-testejä.
Tehtävä 2*
M: 13. Ehtolauseet, M: 9. Aliohjelman paluuarvo
Kirjoita funktio Itseisarvo
, joka antaa luvun itseisarvon, eli annetun luvun etäisyyden nollasta lukusuoralla. Funktiota tulee voida kutsua seuraavasti.
Math.Abs
-funktiota, tai mitään muutakaan valmista funktiota ei saa käyttää.
Ohjelmassa on valmiina luokka ja pääohjelma (ks. Näytä koko koodi). Pääohjelma sisältää tarkistinkoodin, joten et näe pääohjelmaa kokonaan. Laita palautuslaatikkoon pelkkä tekemäsi funktio, ei muuta.
Voit halutessasi kirjoittaa omia ComTest-testejä.
Arviointi: Tehtävässä on automaattinen arviointi.
Tehtävä 3
Kirjoita funktio Etaisyys
, joka palauttaa kahden luvun välisen etäisyyden. Funktiota tulee voida kutsua seuraavasti.
double a, b;
a = 3.2; // Nämä ovat esimerkkilukuja.
b = 8.5; // Luonnollisesti nämä voisivat olla muitakin lukuja.
double etaisyys = Etaisyys(a, b);
Esimerkiksi Etaisyys(3.2, 8.5)
on likimain 5.3, kuten luonnollisesti myös Etaisyys(8.5, 3.2)
. Edelleen, Etaisyys(-1, 1)
on 2. Kannattaa hyödyntää edellisessä tehtävässä luomaasi Itseisarvo
-funktiota.
Ohjelmassa on valmiina luokka ja pääohjelma (ks. Näytä koko koodi). Pääohjelma sisältää tarkistinkoodin, joten et näe pääohjelmaa kokonaan. Laita palautuslaatikkoon pelkkä tekemäsi funktio, ei muuta.
Voit halutessasi kirjoittaa omia ComTest-testejä. Muista, että ComTestissä double-lukujen yhtäsuuruutta vertaillaan kolmella matomerkillä (~~~
).
Arviointi: Tehtävässä on automaattinen arviointi.
Tehtävä 4
Tee funktio Keskiarvo, joka ottaa vastaan kokonaislukuja sisältävän taulukon, ja palauttaa niiden keskiarvon.
// Esimerkkitaulukko
int[] luvut = { 10, 3, 5, 7, 12, 105, 10, 2, -1, 15, 20 };
double keskiarvo = Keskiarvo(luvut);
Console.WriteLine($"Keskiarvo on {keskiarvo}.");
Yllä oleva esimerkki palauttaisi keskiarvoksi noin 17.0909. Jos luvut-taulukko on tyhjä, tulee funktion palauttaa 0.0, ja pääohjelmassa tulee tulostaa teksti "Taulukko on tyhjä". Keskiarvo-funktio ei saa tulostaa mitään.
Ohjelmassa on valmiina luokka ja pääohjelma (ks. Näytä koko koodi). Pääohjelma sisältää tarkistinkoodin, joten et näe pääohjelmaa kokonaan. Laita palautuslaatikkoon pelkkä tekemäsi funktio, ei muuta.
Voit halutessasi kirjoittaa omia ComTest-testejä.
Arviointi: Tehtävässä on automaattinen arviointi.
Tehtävä 5
Muuta Keskiarvo-funktiota niin, että jos aineistossa tulee vastaan negatiivinen luku, palautetaan keskiarvo siihen asti käsitellyistä luvuista. Aineiston käsittely loppuu siihen. Jos aineisto ei sisällä yhtään sopivaa lukua, tulee funktion palauttaa 0.0.
Esimerkki:
// Esimerkkitaulukko
int[] luvut = { 10, 3, 5, -1, 15, 20 };
double keskiarvo = Keskiarvo(luvut);
Console.WriteLine($"Keskiarvo on {keskiarvo}.");
Tämä ohjelma tulostaa 6, koska (10 + 3 + 5) / 3 = 6. Lukua -1 ja sen jälkeen olevaa aineistoa ei oteta mukaan.
Ohjelmassa on valmiina luokka ja pääohjelma (ks. Näytä koko koodi). Pääohjelma sisältää tarkistinkoodin, joten et näe pääohjelmaa kokonaan. Laita palautuslaatikkoon pelkkä tekemäsi funktio, ei muuta.
Voit halutessasi kirjoittaa omia ComTest-testejä.
Arviointi: Tehtävässä on automaattinen arviointi.
Tehtävä 6
Muuta edellistä funktiota niin, että määrittelet funktiolle uuden parametrin nimeltä minimi (int-tyyppinen). Jos aineistossa tulee vastaan luku, joka on pienempi tai yhtäsuuri kuin kyseinen minimi-arvo, se hylätään, mutta aineiston käsittelyä kuitenkin jatketaan.
Jos aineisto ei sisällä yhtään sopivaa lukua, tulee funktion palauttaa minimi-parametrin arvo.
Esimerkki:
// Esimerkkitaulukko
int minimi = 3;
int[] luvut = { 11, 4, 2, 6 };
double keskiarvo = Keskiarvo(luvut, minimi);
Console.WriteLine($"Keskiarvo on {keskiarvo}.");
Tämä ohjelma tulostaa 7, koska (11 + 4 + 6) / 3 = 7. Lukua 2 ei oteta mukaan, koska vain minimi-parametria suuremmat luvut otetaan mukaan.
Vinkki: Voit tehdä funktiosta uuden version kahdella parametrilla ("aliohjelman kuormitus"), niin ei tarvitse välttämättä tuhota edellistä vastaustasi.
Voit halutessasi kirjoittaa omia ComTest-testejä.
Arviointi: Tehtävässä on automaattinen arviointi.
V1
Tee Ville-tehtävät: 5.6-5.8, 9.4-9.6. Muista: Villen käyttöohje
B1
Muuta Tehtävän 6 Keskiarvo-funktiota lisäämällä siihen uusi parametri nimeltä maksimi. Jos aineistossa tulee vastaan luku, joka on vähintään yhtä suuri kuin kyseinen maksimiarvo, aineiston käsittely päättyy siihen.
// Esimerkki 1
int minimi = -7
int maksimi = 99
int[] luvut = { -5, 1, -4, 0, 98 };
double keskiarvo = Keskiarvo(luvut, minimi, maksimi);
Console.WriteLine($"Keskiarvo on {keskiarvo}.");
Tämä ohjelma tulostaisi 18. Aineisto on kokonaisuudessaan minimin ja maksimin välissä, joten lasketaan "tavallinen" keskiarvo.
// Esimerkki 2
int minimi = 3;
int maksimi = 99;
int[] luvut = { 11, 4, 2, 6, 99, 12, 0, -3 };
double keskiarvo = Keskiarvo(luvut, minimi, maksimi);
Console.WriteLine($"Keskiarvo on {keskiarvo}.");
Tämä tulostaisi 7. Vain luvut 11, 4, ja 6 lasketaan keskiarvoon mukaan: 2 on alle minimin, ja käsittely päättyy lukuun 99.
Voit taas tehdä funktiosta uuden version kahdella parametrilla ("aliohjelman kuormitus"), niin ei tarvitse välttämättä tuhota edellistä vastaustasi.
Voit halutessasi kirjoittaa omia ComTest-testejä.
Arviointi: Tehtävässä on automaattinen arviointi.
B2-3
Tämä tehtävä on poikkeuksellisesti kahden pisteen arvoinen.
Antti-Jussi haluaa myydä asuntonsa. Hän on saanut eri kiinteistönvälittäjiltä useita hinta-arvioita asunnostaan, ja pohtii nyt, mikä olisi sellainen myyntihinta, joka ei ole liian korkea (koska silloin asunto ei mene kaupaksi), mutta ei myöskään liian matala (koska silloin hän ei saa parasta mahdollista hintaa). Hän päätyy seuraavaan ratkaisuun.
Hän laskee ensin kaikkien hinta-arvioiden keskiarvon. Sitten hän laskee, kuinka paljon kukin hinta-arvio poikkeaa tästä keskiarvosta. Paras hinta-arvio (ja siten myös paras välittäjä Antti-Jussin määritelmän mukaan) on se, jonka poikkeama on pienin. Jos tällaisia hinta-arvioita on useita, paras hinta-arvio on näistä suurin. Antti-Jussi valitsee tämän kiinteistövälittäjän.
Merkitään asuntojen hinta-arvioita yksinkertaisuuden vuoksi lukuina siten, että 100 tarkoittaa 100 tuhatta euroa, 105 tarkoittaa 105 tuhatta euroa, jne.
Esimerkiksi jos Antti-Jussin asunnosta on saatu hinta-arviot 100, 110, 90, 105 ja 115, niin niiden keskiarvo on 104. Poikkeamat ovat 4, 6, 14, 1 ja 11. Paras hinta-arvio on 105, koska se on lähimpänä keskiarvoa (poikkeama on 1).
Tee funktio ParasHintaArvio
, joka ottaa hinta-arviot (int-taulukko) ja palauttaa niiden perusteella sen hinta-arvion, joka on lähimpänä taulukon lukujen keskiarvoa.
Vinkit:
- Tee ensin funktio
Summa
. SittenKeskiarvo
, joka laskee hinta-arvioiden keskiarvon. - Tee sitten funktio
Itseisarvo
, tai käytä aiemmassa tehtävässä tekemääsi toteutusta. Tarvitset tätä funktiota laskeaksesi kunkin hinta-arvion poikkeaman keskiarvosta. - Tarvitset myös
Etaisyys
-funktiota, kun lasketaan kunkin alkion etäisyyttä keskiarvosta. Jos et tehnyt tätä funktiota aiemmin, tee se nyt. - Huomaa, että keskiarvo voi olla desimaaliluku, samoin yksittäisen luvun poikkeama keskiarvosta.
Saattaa olla hyödyllistä aluksi unohtaa koko C# ja tee kynällä ja paperilla vastaava tehtävä ja mieti vaiheittain mitä joudut tekemään ja mitä apumuuttujia käyttämään. Ajattele niin, että joku näyttää sinulle yksi kerrallaan yhtä lukua, et tiedä tulevia etkä muistele menneitä, joten sinun täytyy "pitää muistissa" tietoa siitä, mikä on tähän mennessä lähinnä etsittävää lukua.
Kahden luvun välinen etäisyys on lukujen erotuksen itseisarvo.
Arviointi: Tehtävässä on automaattinen arvostelu. Jos automattinen arvostelu antaa mielestäsi väärät pisteet sinulle, käytä Mukautetut pisteet -toimintoa ja arvioi oma suorituksesi asteikolla: 25% = 0.5 p, 50% = 1 p., 75% = 1.5 p., 100% = 2 p.
Moi! Puuttuukohan tästä tarkistuskoodista public class rivi? Rideri herjasi tuota ja en saa täällä nyt toimimaan, kun yritän palauttaa ja tarkistella.
Ei puutu, mutta se on piilotettu (automaattitarkistimen takia). Ratkaisussasi on ainakin pari virhettä: paluuarvon tyyppi ja toiminta "yhtä hyvien" tarjousten kanssa. Katso tehtävän kuvaus vielä uudestaan. -AJL
—Tilastotieteessä käytetään useita erilaisia keskilukuja, kuten keskiarvo, mediaani ja moodi. Yksi lisää voisi olla keskiarvoa lähinnä oleva joukon alkio, josta tässä käytetään nimitystä miidi - tällaista keskilukua ei siis oikeasti ole olemassa. Esimerkiksi taulukon {1, 2, 3, 2, 5}
keskiarvo on 2.6, joten tämän taulukon alkioista luku 3 on kaikkein lähimpänä tätä keskiarvoa. Toisin sanoen luvun 3 "etäisyys" keskiarvosta 2.6 on kaikkein pienin.
Tee Miidi
-niminen funktio, joka palauttaa reaalilukutaulukon lukujen miidin, eli sen alkion joka on lähimpänä taulukon keskiarvoa. Mikäli taulukossa on useita alkioita jotka ovat yhtä lähellä keskiarvoa, funktion tulee palauttaa ensimmäinen näistä.
Et valitettavasti voi käyttää hyväksesi (eli kutsua) luentojen Summa
-funktiota (koska se oli int
-taulukolle), vaan joudut kopioimaan sen ja muuttamaan taulukon tyypin. Aloita kuitenkin tekemällä tuo reaalilukutaulukon keskiarvon laskeva funktio. Voit testata vaikka aineistolla:
double[] luvut1 = { 1, 2, 3, 2, 5 }; // Vihje: Tässä keskiarvo == 2.6, mikä on silloin miidi?
double miidi1 = Miidi(luvut1); // 3
double[] luvut2 = new double[] { 1 };
double miidi2 = Miidi(luvut2); // 1
double[] luvut3 = new double[] { 3, 3 };
double miidi3 = Miidi(luvut3); // 3
double[] luvut4 = new double[] { };
double miidi4 = Miidi(luvut4); // 0
Vinkki 1: Lähimmän etsimiseksi unohda aluksi koko C# ja tee kynällä ja paperilla vastaava tehtävä ja mieti vaiheittain mitä joudut tekemään ja mitä "apumuuttujia" käyttämään. Ajattele niin, että joku näyttää sinulle yksi kerrallaan yhtä lukua, et tiedä tulevia etkä muistele menneitä, joten sinun täytyy "pitää muistissa" tietoa siitä, mikä on tähän mennessä lähinnä etsittävää lukua.
Vinkki 2: Tehtävän ratkaisuun on muutamia eri tapoja. Voit lähteä seuraavasta: Tee (ellet jo tehnyt) funktiot Itseisarvo
(tehtävän 2 mukaisesti), Etaisyys
(tehtävän 3 mukaisesti), Summa
, Keskiarvo
, ja vasta viimeisenä funktio Miidi
, joka hyödyntää edellä mainittuja funktioita.
Arviointi: Tehtävässä saa kääntyvästä ohjelmasta 0.2 p. + kattavasta testaamisesta + 1.1 p. + oikeasta tulostuksesta 0.7 p. Ellei TIM anna täysiä pisteitä, voit tarvittaessa antaa itsellesi Custom Pointsit oikein tehdyistä apufunktioista seuraavasti: Itseisarvo 0.2 p., Etäisyys 0.2 p., Summa 0.2 p., Keskiarvo 0.2 p.
B4
Lue: Aliohjelmien kirjoittaminen
Tee seuraavia funktiokutsuja vastaavat funktioiden esittelyrivit ja lyhyimmät mahdolliset toteutukset (tynkä), jotta ohjelma kääntyy. Näin ohjelmasta saadaan syntaktisesti toimiva, mutta sen ei tarvitse toimia loogisesti oikein. Muista kirjoittaa myös dokumentaatiot: niiden tekeminen onnistuu, vaikka ohjelma ei vielä toimikaan loogisesti oikein.
Pisteiden saamiseksi funktioiden esittelyrivit pitää olla kirjoitettu oikein, funktion pitää palauttaa oikean tyyppinen arvo ja funktio pitää olla dokumentoitu asianmukaisesti. Kustakin kohdasta a-e saa 0.2 pistettä.
Esimerkki (älä kopioi tätä):
Tehtävässä annetaan pääohjelma valmiina. Ohessa esimerkki.
/// <summary>Funktiokutsu ja apumuuttuja</summary>
/// <param name="args">Ei käytössä</param>
public static void Main(string[] args)
{
string lyhyempi = LyhyempiJono("Matti", "Pertti");
}
Tämä koodi ei kuitenkaan käänny, koska LyhyempiJono
-funktiota ei ole olemassa. Niinpä seuraava koodi (aliohjelman esittelyrivi sekä toteutuksen "tynkä") pitää itse kirjoittaa.
/// <summary>
/// Palauttaa kahdesta merkkijonosta lyhyemmän.
/// </summary>
/// <param name="s1">Ensimmäinen jono</param>
/// <param name="s2">Toinen jono</param>
/// <returns>Lyhyempi jonoista</returns>
public static string LyhyempiJono(string s1, string s2)
{
return s1;
}
Nyt ohjelma kääntyy. Funktio ei vielä oikeasti palauta lyhyempää jonoa, mutta tämä riittää tämän tehtävän vastaukseksi.
Vinkki: a-kohdassa funktion toteutukseksi riittää pelkkä return false;
.
Huomaa, että d-kohdassa ei todella tarvitse laittaa lukuja palautettavan double
-taulukon sisällöksi. Tyhjä double-taulukko riittää paluuarvoksi.
B5
Pythagoraan lauseen avulla voidaan laskea 2-ulotteisella tasolla olevan kahden pisteen välisen etäisyys.
Tee funktio Etaisyys
, jonka esittelyrivi on seuraava:
Arviointi:
- kääntyvä ohjelma 0.1 p.
- itse kirjoitetut testit ja testien läpäiseminen 0.5 p.
- oikea tulostus 0.4 p.
Kannattaa rajoittaa Comtest-testeissä liukulukujen vertailutarkkuutta käyttämällä TOLERANCE-ominaisuutta, ks. kohta Testaaminen.
TODO opettajille: Math.Sqrt:n käyttö.
B6
M: 9. Aliohjelman paluuarvo. Tee funktio
Skaalaa(double luku, double min, double max)
joka skaalaa välillä [0, 1]
olevan luvun välille [min, max]
. Esimerkkejä:
Skaalaa(0.2, -3, 3) ~~~ -1.8;
Skaalaa(0.2, 1, 6) ~~~ 2.0;
Skaalaa(0.0, 1, 6) ~~~ 1.0;
Skaalaa(1.0, 1, 6) ~~~ 6.0;
Eli esimerkiksi ensimmäinen testitapaus tarkoittaa että välin \([0, 1]\) luku \(0.2\) on omaan väliinsä nähden samassa suhteessa kuin luku \(-1.8\) on väliin \([-3, 3]\).
Piirrä vaikka molemmat välit ja ko. luvut oman välinsä sisälle.
Vinkki: jos sinulla on luku väliltä \([0, 1]\) ja haluat saada siitä luvun välille \([a, b]\), niin mieti mitä pitää tehdä jotta \(0\):sta tulisi \(a\) ja \(1\):stä b. (eli \(f(x) = a + (b-a)*x\)).
Perustelu: Edellä vinkissä on väli \([0, 1]\) esimerkkinä, koska ohjelmointikielten tyypillinen satunnaislukugeneraattori tuottaa lukuja puoliavoimelle välille ja jatkossa meillä on tälle Skaalaa
-funktiolle käyttöä nimenomaan tuottamaan satunnaisia lukuja muillekin väleille. Tosin onneksi esim. Jypelissä tämä on valmiina. Pyöristysten kanssa on nimittäin oltava tarkkana :-)
Arviointi: Tehtävässä saa sen ajamisesta 0.1 p. + testien tekemisestä ja niiden läpäisemisestä + 0.5 p. + oikeasta tulostuksesta 0.3 p. + dokumentaatiosta 0.1 p.
G1
Ota edellisen demokerran Sopulit-tehtävän ratkaisu
ja tee siitä graafinen versio, jossa on paljon ruutuja (suuruusluokkaa 60 y-suunnassa) ja sukupolvia lasketaan 0.1 sekunnin välein.
Luo uusi FysiikkaPeli (PerusPelikin käy aivan hyvin, siinä ei ole fysiikkaa eikä sitä tässä tarvita) ja kopioi luokkaan seuraava koodi.
Liitä projektiin tuo Sopulit.cs ja käytä sitä sukupolvi-taulukoiden päivittämiseen.
Täydennä aliohjelmat (ja metodit) niin, että ohjelma toimii kohdan 1. mukaisesti.
Projektiin liittäminen (kohta 3):
- kopioi tiedosto samaan paikkaan kuin projektin muut .cs tiedostot
- Solution Explorerissa paina hiiren oikeata projektin nimen päällä
- Add -> Existing Item
- valitse lisättävä tiedosto Add
- lisää omaan
.cs
-tiedostoon alkuun (tässä esimerkissä)
using Demo5;
tällöin kääntäjä tietää että esim kutsut:
Sopulit.Arvo(sukupolvi, 0, 1);
Demo5.Sopulit.Arvo(sukupolvi, 0, 1);
ovat samoja.
Koodipohjaa uudelle pelille:
G2
Täydennä GameOfLife siten, että voit näppäimistön Delete-napista tyhjentää kentän ja sitten hiirellä klikkailla päälle ja pois ruutuja. Hiiren klikkaus pysäyttää aina animaation ja sitten voi rauhassa rakentaa haluamansa kuvion (ks: Bitstorm ja Wikipedia) ja sitten laittaa Enter-nappulalla animoinnin uudelleen käyntiin. Välilyönti arpoo kokonaan uuden alkutilanteen.
TDD1
Jos tarkistat vähintään kahden funktion toiminnan ComTestillä, saat merkitä yhden lisäpisteen. Kirjoita alle olevaan vastauslaatikkoon minkä tehtävän ja minkä funktion/funktioiden toiminnan testasit. Voit antaa samalla vastauksen kautta palautetta ja kehitysehdotuksia Comtestin käytöstä.
These are the current permissions for this document; please modify if needed. You can always modify these permissions from the manage page.