Tehtävät

Neljännen viikon tehtävät

Palauta ratkaisusi viimeistään ma 25.11. klo 21:00
Tarkastellaan kolmen tavallisen nopan heittoa, jossa jokaisella nopalla voidaan siis saada yksi luvuista 1–6. Tehtävänäsi on käydä for- ja if-rakenteita käyttäen läpi kaikki mahdolliset yhdistelmät kolmen nopan heitossa saatavista silmäluvuista. Olemme erityisen kiinnostuneita tapauksista, joissa kolmen nopan silmälukujen summa on joko 5 tai jaollinen 10:llä: esim. summa 5 tulee yhdistelmästä (1,1,3) ja 10:llä jaollinen on yhdistelmän (1,3,6) summa. Tulosta kaikki kolmen nopan silmälukujen mahdolliset yhdistelmät (jokainen omalle rivilleen) muodossa
	(1,4,2)
sekä tulosta lisäksi kiinnostavien yhdistelmien rivin loppuun välilyönnillä erotettu * -merkki:
	(1,1,3) *
Lopuksi tulosta omalle rivilleen kaikkien kolmen nopan heiton erilaisten silmälukujen yhdistelmien lukumäärä ja kiinnostavien tapausten (silmälukujen summa 5 tai 10:llä jaollinen) lukumäärä muodossa:
	Kaikki erilaiset kolmen nopan heitot XXX kpl, joista kiinnostavia YY kpl.
missä XXX ja YY ovat lukumäärät. Esimerkkitulostus olisi siis:
	(1,1,1)
	(1,1,2)
	(1,1,3) *
	   .
	   .
	   .
	(6,6,5)
	(6,6,6)
	Kaikki erilaiset kolmen nopan heitot XXX kpl, joista kiinnostavia YY kpl.
Tässä tehtävässä joudut käyttämään sisäkkäisiä for-rakenteita (eri noppien heitoille) ja niistä yhden sisään sijoittamaan if-rakenteen (etsimään kiinnostavat tapaukset).
Kirjoita funktio data_statistics, jolle annetaan sisäänsyöttöparametrina lista tiedostojen nimiä (lista, jonka alkiot ovat merkkijonomuuttujia). Tiedostot on muotoiltu siten, että niiden joka rivillä on yksi luku. Funktio lukee tiedoston kerrallaan, ja laskee kaikkien kyseisessä tiedostossa olevien lukujen keskiarvon, keskihajonnan sekä mediaanin. Voit käyttää datan lukemiseen NumPy:n funktiota loadtxt sekä tunnuslukujen laskemiseen mean, std ja median -funktioita. Testaa kirjoittamasi data_statistics -funktion toimintaa main -funktiossa tehtävänannon tiedostoilla inputdata1.dat ja inputdata2.dat tulostamalla tiedostojen nimet ja luvut kahden desimaalin tarkkuudella:
  Tiedoston inputdata1.dat statistiikka: keskiarvo 24.66, keskihajonta 7.31, mediaani 24.16
  Tiedoston inputdata2.dat statistiikka: keskiarvo 108827.71, keskihajonta 1026863.02, mediaani 202.98
Tee funktio create_equation, joka ottaa ensimmäisenä argumenttinaan listan positiivisia kokonaislukuja sekä toisena argumenttinaan listan plus- ja miinusmerkkejä, jotka ilmoittavat järjestyksessä mitä laskuoperaatioita suoritetaan funktiolle annetun ensimmäisen argumentin listan lukujen välillä. Funktio palauttaa merkkijonon, jossa luvut ja niiden väliset laskutoimitukset on kirjoitettu auki ja koko laskutoimituksen lopputulos yhtäsuuruusmerkin jälkeen. Esimerkki:
	create_equation([2,7,3,1],['+','+','–'])
palauttaa merkkijonon (huomaa välilyönnit laskutoimitusmerkkien, yhtäsuurusmerkin ja numeroiden välissä)
 	'2 + 7 + 3 – 1 = 11'
Varaudu tilanteeseen, että funktiota kutsuttaessa annetut listat eivät ole oikeanpituisia: laskutoimitusmerkkejä pitää olla täsmälleen yksi vähemmän kuin lukuja. Jos näin ei ole, funktio palauttaa tyhjän merkkijonon, eli
	create_equation([2,7,3,1],['+','+'])
palauttaa merkkijonon
	''
Poikkeuksena tähän sallitaan tilanne, että toisena argumenttina funktiolle annetaan yhden alkion pituinen lista, joko ['+'] tai ['-']. Tällöin käytetään tätä laskutoimitusta kaikkien annettujen lukujen välillä, eli
	create_equation([2,7,3,1],['-'])
palauttaa merkkijonon
	'2 - 7 - 3 - 1 = -9'
Muihin poikkeustilanteisiin ei tarvitse varautua. Testaa kirjoittamasi create_equation -funktion toimintaa main -funktiossa yllä kaikkien olevien kolme esimerkin tapauksessa tulostamalla niiden palauttamat merkkijonot järjestyksessä:
	2 + 7 + 3 – 1 = 11
	
	2 - 7 - 3 - 1 = -9
Tämän tehtävän ratkaisusta saat 3 pistettä.
Olemme tähän mennessä kurssilla käyttäneet Pythonin listamuuttujista tyyppejä list ja tuple. Tutustutaan seuraavaksi Numpy-kirjaston avulla taulukoihin (engl. array). Taulukot voivat listamuuttujista poiketen olla useampiulotteisia, mutta pitää sisällään vain yhdentyyppisiä arvoja (esim. taulukon kaikki alkiot tyyppiä float). NumPy otetaan käyttöön komennolla
	import numpy as np
jonka jälkeen kaikki NumPyn funktiot ovat kutsuttavissa pistenotaatiolla: np.funktionnimi() Tieteellisessä laskennassa ehkäpä useimmin vastaantuleva taulukko on kaksiulotteinen, joka määritellään antamalla taulukon rivit listojen listana:
	In [1]: a = np.array([[1,2,3], [4,5,6], [7,8,9]])
	In [2]: a
	Out[2]:
	array([[1, 2, 3],
	       [4, 5, 6],
	       [7, 8, 9]])
Taulukon alkioihin viitataan []-sulkeissa pilkuilla erotettujen indeksien avulla. Kaksiulotteisilla taulukolla ensimmäinen indeksi viittaa taulukon riviin ja toinen sen sarakkeeseen, ja indeksointi alkaa 0:sta kuten listamuuttujillakin. Tietty osa taulukosta saadaan poimittua antamalla halutun indeksivälin alku ja loppu : -merkillä erotettuna. Koko rivi tai sarake saadaan poimittua pelkällä : -merkillä. Esim. edellämääritellylle taulukolle a
	In [3]: a[0,2]
	Out[3]: 3
	In [4]: a[1:3,0:2]
	Out[4]: 
	array([[4, 5],
 	      [7, 8]])
	In [5]: a[0,:]
	Out[5]: array([1, 2, 3])
Taulukon koon saa selville shape ja size -funktioilla:
	In [69]: np.shape(a)
	Out[69]: (3, 3)
	In [70]: np.size(a)
	Out[70]: 9
Taulukkoja voidaan käyttää peruslaskutoimituksissa (samankokoisia taulukoita voidaan laskea yhteen, vähentää, kertoa ja jakaa) ja monien funktioiden argumentteina. Tällöin laskutoimitukset suoritetaan alkioittain ja tuloksena saadaan alkuperäisen kanssa samankokoinen taulukko (huomaa erityisesti, että * -merkillä tehty kertolasku samankokoisten taulukoiden välillä on nimenomaan alkioittainen kertolasku, eikä matriisikertolasku). Kokeile taulukkolaskuja määrittelemällä taulukot
	a=np.array([[1,2,3], [4,5,6], [7,8,9]])
	b=np.array([[-2.0,2.5,3.8], [0.1,-17.9,6.0], [7.1,8.8,10.3]])
ja laske näiden taulukoiden summa, tulo, summan sini sekä summan kolmas potenssi. Määritä näiden neljän tulostaulukon pienin ja suurin alkio, ja tulosta nämä
        Taulukon a+b pienin ja suurin alkio: XX1_min, XX1_max
	Taulukon a*b pienin ja suurin alkio: XX2_min, XX2_max
	Taulukon sin(a+b) pienin ja suurin alkio: XX3_min, XX3_max
	Taulukon (a+b)**3 pienin ja suurin alkio: XX4_min, XX4_max
missä luvut XX1_min, XX1_max jne. ovat kyseisten taulukoiden pienimmät ja suurimmat alkiot tulostettuna desimaalilukuina kolmen desimaalin tarkkuudella.
NumPy:ssa on myös matriisimuuttuja (engl. matrix), joka käyttäytyy muuten kuin taulukkomuuttuja, mutta matriisimuuttujien kertolasku on määritelty samain kuin matematiikassa (eli kahdelle samankokoiselle matriisille tai erikokoisille matriiseille, joista ensimmäisessä on sama määrä sarakkeita kuin jälkimmäisessä on rivejä). Kokeile nyt matriisien laskutoimituksia määrittelemällä ensin edellisen tehtävän taulukot myös matriiseina:
	a=np.array([[1,2,3], [4,5,6], [7,8,9]])
	b=np.array([[-2.0,2.5,3.8], [0.1,-17.9,6.0], [7.1,8.8,10.3]])
	A=np.mat([[1,2,3], [4,5,6], [7,8,9]])
	B=np.mat([[-2.0,2.5,3.8], [0.1,-17.9,6.0], [7.1,8.8,10.3]])

ja laskemalla summa, tulo, summan sini sekä summan kolmas potenssi sekä taulukoiden a ja b välillä että matriisien A ja B välillä. Vertaile saamiasi tuloksia, esim. summalle:
	In [1]: summa_taulukko = a + b
	In [2]: summa_matriisi = A + B
	In [3]: summa_taulukko == summa_matriisi
	Out[3]: 
	matrix([[ True,  True,  True],
		  [ True,  True,  True],
	        [ True,  True,  True]])

eli matriisien välinen yhteenlasku tapahtuu samanlailla alkioittain kuin taulukoilla ja tuottaa saman tuloksen. Voimme myös vertailla, ovatko kaikki alkiot samoja vai ei NumPy:n all -funktion avulla
	In [4]: np.all(summa_taulukko==summa_matriisi)
	Out[4]: True

Eli tässä tapauksessa, kun kaikki alkiot ovat keskenään samat, all -funktio palauttaa totuusarvon True. Tee vertailut (if – else -rakenteella) kaikille neljälle laskutoimitukselle (summa, tulo, summan sini sekä summan kolmas potenssi) ja tulosta vertailujen perusteella:
	Taulukkojen ja matriisien summat ovat samat
	Taulukkojen ja matriisien tulot eivät ole samat
	Taulukkojen ja matriisien summan sinit ovat samat
	Taulukkojen ja matriisien potenssit eivät ole samat

Varsinkin laboratoriotöissä haluamme usein sovittaa dataan suoran y = ax + b ja tietää sen kulmakertoimen a ja vakiotermin b arvot. Pythonin avulla tämän voi toteuttaa hyödyntämällä pienimmän neliösumman menetelmää. Olet mitannut virtaa ja jännitettä yksinkertaisessa virtapiirissä, jossa on vastus. Ohmin lain mukaan jännite U vastuksen yli on suoraan verrannollinen virtapiirissä kulkevaan virtaan, U = RI. Sovittamalla mittausdataan (I, U) suoran saamme siten selville vastuksen R suuruuden. Mittausdata on tiedostossa input.dat, jossa ensimmäisellä sarakkeella on virta (yksiköissä milliampeeri eli 10–3 A) ja toisella sarakkeella jännite (voltteina). Tee suoran sovitus dataan käyttämällä NumPy:n polyfit -funktiota. Tulosta saamasi kulmakerroin eli vastuksen arvo desimaalilukuna yhden desimaalin tarkkuudella:
  R = 101.7 ohmia

Sisällysluettelo