Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1
CSE-A1111
16.9.2015
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
1 / 26
Mahdollisuus antaa luentopalautetta
I
Goblinissa vasemmassa reunassa olevassa valikossa on valinta
”Luentopalaute”. Tätä kautta on mahdollisuus antaa nimettömänä
palautetta luennosta.
I
Jos jokin asia on jäänyt palautteen perusteella epäselväksi, palataan
siihen mahdollisuuksien mukaan seuraavalla luennolla.
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
2 / 26
Oppimistavoitteet: tämän luennon jälkeen
I
Osaat kirjoittaa ohjelman, joka toistaa haluttua käskyä tai käskyjonoa
niin, että käskyjono tarvitsee kirjoittaa vain yhteen kertaan. Viime
kerralla opittujen asioiden lisäksi:
I
I
I
Osaat käyttää myös for-käskyä while-käskyn lisäksi.
Tiedät, miten voit käyttää toistokäskyä hyväksi, jos haluat ratkaista
jonkin yhtälön iteroimalla.
Osaat muotoilla tulostusta niin, että ohjelmasi tulostaa esimerkiksi
desimaaliluvuista vain halutun määrän desimaaleja tai tulostaa
allekkain desimaalilukuja samoihin sarakkeisiin.
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
3 / 26
Kertausta: lämpötilojen keskiarvo while-käskyn avulla
def main():
rivi = input("Montako lampotilaa annat?\n")
lkm = int(rivi)
i = 0
summa = 0.0
while i < lkm:
rivi = input("Anna seuraava lampotila.\n")
lampotila = float(rivi)
summa = summa + lampotila
i = i + 1
if lkm > 0:
keskiarvo = summa / lkm
print("Lampotilojen keskiarvo on", keskiarvo)
else:
print("Et antanut yhtaan lampotilaa.")
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
4 / 26
If-käsky toistokäskyn sisällä
def main():
HELLERAJA = 25.0
print("Anna lampotiloja, lopeta -300:lla.")
hellepaivien_lkm = 0
rivi = input("Anna ensimmainen lampotila.\n")
lampotila = float(rivi)
while lampotila > -300.0:
if lampotila >= HELLERAJA:
hellepaivien_lkm += 1
rivi = input("Anna seuraava lampotila.\n")
lampotila = float(rivi)
print("Hellepaivia oli", hellepaivien_lkm, "kpl.")
main()
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
5 / 26
Toistokäsky for
I
For-käskyn avulla voidaan käydä jonkun rakenteen alkiot
järjestyksessä.
I
Funktion range avulla voidaan generoida lukujono (ei täsmällisesti
oikea termi), jonka kaikki alkiot voidaan käydä läpi for-käskyn avulla.
I
Esimerkiksi range(11) generoi lukujonon, joka sisältää luvut 0:sta
10:een asti.
I
Voidaan kirjoittaa toistokäsky
for i in range(11):
tee jotain arvolle i
jossa i saa vuorotellen arvot 0–10.
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
6 / 26
Esimerkki: kertotaulu for-käskyn avulla
def main():
for i in range(11):
tulos = i * 6
print(i, "* 6 =", tulos)
main()
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
7 / 26
Lisää range-funktiosta
I
Lukujonoja generoidessa voi antaa myös jonon ensimmäisen alkion,
esimerkiksi range(1, 11) generoi lukujonon, jonka ensimmäinen
alkio on 1 ja viimeinen 10.
I
On myös mahdollista antaa jonon kahden peräkkäisen alkion väli,
esimerkiksi range(1, 11, 2) generoi lukujonon, joka sisältää luvut
1, 3, 5, 7 ja 9.
I
Väli voi olla myös negatiivinen, jolloin lukuja generoidaan ylhäältä
alaspäin. Esimerkiksi range(10, 1, -2) generoi lukujonon, joka
sisältää luvut 10, 8, 6, 4 ja 2.
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
8 / 26
Kertotaulu uudelleen
def main():
for i in range(1, 11):
tulos = i * 6
print(i, "* 6 =", tulos)
main()
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
9 / 26
Hellepäivien lukumäärä for-käskyn avulla
def main():
HELLERAJA = 25.0
rivi = input("Montako lampotilaa annat?\n")
lkm = int(rivi)
hellepaivien_lkm = 0
for i in range(lkm):
rivi = input("Anna seuraava lampotila.\n")
lampotila = float(rivi)
if lampotila >= HELLERAJA:
hellepaivien_lkm += 1
print("Hellepaivia oli", hellepaivien_lkm, "kpl.")
main()
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
10 / 26
Välitehtävä
I
Miten muuttaisit aikaisemmin annettua lämpötilojen keskiarvon
laskevaa ohjelmaa, jos sen ei pitäisikään laskea lämpötilojen
keskiarvoa, vaan niiden maksimi?
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
11 / 26
Iterointiesimerkki
I
Insinöörimatematiikassa pitää usein ratkaista jokin yhtälö iteroimalla:
I
I
I
Arvataan yhtälölle jokin ratkaisu.
Jos arvaus ei ole tarpeeksi hyvä, sijoitetaan edellinen arvaus johonkin
kaavaan ja saadaan tällä tavalla uusi arvaus.
Tätä jatketaan, kunnes arvaus on tarpeeksi hyvä tai todetaan, että
ratkaisua ei löydy tällä tavalla.
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
12 / 26
Neliöjuuri Newtonin iteraatiolla
I
I
Haetaan luvun x neliöjuuri.
Newtonin iteraatio: jos funktion f (y ) nollakohdalle on arvaus yn , niin
parempi arvaus saadaan kaavalla
yn+1 = yn −
I
I
I
f (yn )
f 0 (yn )
Tässä tapauksessa lasketaan funktion f (y ) = y 2 − x nollakohtaa,
jolloin kaavaksi saadaan
1
x
yn+1 = (yn + )
2
yn
Pitää vielä päättää, koska saatu ratkaisu on tarpeeksi hyvä. Tässä
esimerkissä lopetetaan, kun kahden peräkkäisen arvauksen erotuksen
itseisarvo on korkeintaan 0.0001.
Huomautus: neliöjuuren laskemiseen löytyy Pythonista myös valmis
funktio, mutta samalla periaatteella voidaan ratkaista monia muita
yhtälöitä.
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
13 / 26
Neliöjuuri iteroimalla, koodi
def main():
TARKKUUS = 0.0001
rivi = input("Minka luvun neliojuuri lasketaan? ")
x = float(rivi)
if x <= 0:
print("Ohjelma toimii vain positiivisilla luvuilla.")
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
14 / 26
Neliöjuuri iteroimalla, koodi jatkuu
else:
arvaus = 1.0
uusi_arvaus = 0.5 * (arvaus + x / arvaus)
while abs(uusi_arvaus - arvaus) > TARKKUUS:
arvaus = uusi_arvaus
uusi_arvaus = 0.5 * (arvaus + x / arvaus)
print("luvun", x, "neliojuuri on", uusi_arvaus)
main()
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
15 / 26
Tulostuksen muotoilu
I
Tavallisesti print-käsky käyttää Pythonin oletustarkkuuksia esim.
desimaalilukuja tulostaessaan.
I
Usein ohjelmoija haluaisi kuitenkin vaikuttaa desimaalilukujen
tulostusten tarkkuuteen.
I
Lisäksi tulostuskenttien leveyksiä säätämällä voidaan vaikuttaa siihen,
että päällekkäisillä riveillä toisiaan vastaavat asiat saadaan
tulostumaan omiin sarakkeihinsa.
I
Näihin asioihin voidaan vaikuttaa tulostuksen muotoilulla.
I
Seuraavassa ei esitetä läheskään kaikkia muotoilumahdollisuuksia,
vaan vain tärkeimmät perusasiat.
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
16 / 26
Miten tulostusta muotoillaan?
I
print-käskyssä kirjoitetaan ensin lainausmerkkien sisälle tulostettava
vakioteksti.
I
Tekstin keskelle lisätään aaltosulut ja niiden sisään muotoilumääre
sellaiseen paikkaan, johin tulostuksessa halutaan tulevan joku
muotoiltava arvo, esimerkiksi muuttujan arvo.
I
Lainausmerkeissä olevan tekstin jälkeen kirjoitetaan piste, käsky
format ja sen sulkujen sisälle muotoiltavat arvot (esim. muuttujien
nimet) toisistaan pilkulla erotettuna.
I
Esimerkki:
luku1 = 4.579875
tulo = luku1 * luku1
print("Luku on {:4.3f}".format(luku1))
print("{:4.2f} toiseen on {:6.2f}".format(luku1, tulo))
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
17 / 26
Muotoilumääre
I
Muotoilukoodi alkaa kaksoispisteellä.
I
Merkin jälkeen voidaan antaa kokonaislukuna tulostukselle varattavan
kentän leveys. Jos sitä ei anneta, tulostustettavalle arvolle varataan
tarpeellinen määrä tilaa.
I
Tämän jälkeen desimaaliluvuilla voidaan antaa piste ja sen jälkeen
käytettävä tarkkuus (desimaalien määrä) kokonaislukuna.
I
Lopuksi tulee määrittelykirjain, joka kertoo, millaista arvoa ollaan
tulostamassa:
d kokonaisluku
f desimaaliluku ilman eksponenttiosaa
e desimaaliluku eksponenttiosan kanssa
E desimaaliluku eksponenttiosan kanssa
g desimaaliluku
s merkkijono
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
18 / 26
Huomautuksia muotoilukoodeista
I
Määrittelykirjainta g käytettäessä desimaaliluku tulostetaan joko
ilman eksponenttiosaa tai sen kanssa luvun suuruuden mukaan.
Muotoilukoodissa annettu tarkkuus ei tällöin tarkoita desimaalien
määrää, vaan merkitsevien numeroiden määrää.
I
Oletusarvoisesti luvut tulostetaan kentän oikeaan reunaan. Jos
halutaan tulostus kentän vasempaan reunaan, lisätään
muotoilumääreen alkuun :-merkin jälkeen <
I
Merkkijonot tulostetaan oletusarvoisesti kentän vasempaan reunaan.
Ne voidaan siirtää oikeaan reunaan >-merkillä.
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
19 / 26
Esimerkki: sijoituksen arvokehitys
I
Käyttäjä antaa ohjelmalle sijoitettavan pääoman, oletetun
vuosituoton ja sijoitusajan.
I
Ohjelma laskee ja tulostaa sijoituksen arvon kunkin vuoden lopussa
sekä vuoden aikana kertyneen koron.
I
Käytetään tulostuksen muotoilua siihen, että eri vuosien tiedot
tulostuvat kauniisti päällekkäin omiin sarakkeihinsa.
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
20 / 26
Sijoituksen arvokehitys, koodi
def main():
print("Ohjelma laskee sijoituksen arvon kehittymisen.")
vastaus = input("Anna sijoitettava paaoma.\n")
paaoma = float(vastaus)
vastaus = input("Anna sijoitusaika.\n")
aika = int(vastaus)
vastaus = input("Anna vuosituotto (%).\n")
tuotto = float(vastaus)
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
21 / 26
Sijoituksen arvokehitys, koodi jatkuu
i = 0
print("vuosi vuosikorko paaoma")
print("
vuoden lopussa")
while i < aika:
korko = tuotto / 100.0 * paaoma
paaoma = paaoma + korko
i = i + 1
print("{:4d}. {:10.2f} {:12.2f}".format(
i, korko, paaoma))
main()
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
22 / 26
Jatko for-käskyn avulla
print("vuosi vuosikorko paaoma")
print("
vuoden lopussa")
for i in range(1, aika + 1):
korko = tuotto / 100.0 * paaoma
paaoma = paaoma + korko
print("{:4d}. {:10.2f} {:12.2f}".format(
i, korko, paaoma))
main()
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
23 / 26
Sisäkkäiset toistokäskyt
I
Toistokäskyn sisällä voi olla toinen toistokäsky.
I
Tällöin sisempi toistokäsky suoritetaan kokonaan eli sen kaikki
kierrokset suoritetaan jokaisella ulomman toistokäskyn kierroksella.
I
Seuraavien kalvojen esimerkkiohjelmat tulostavat kellonaikoja (tunnit
ja minuutit) yhden minuutin välein. Minuutteja muutetaan
sisemmässä toistokäskyssä ja tunteja ulommassa toistokäskyssä.
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
24 / 26
Kello for-käskyn avulla
def main():
for tunnit in range(24):
for minuutit in range(60):
print(tunnit, ":", minuutit)
main()
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
25 / 26
Kello while-käskyn avulla
def main():
tunnit = 0
while tunnit < 24:
minuutit = 0
while minuutit < 60:
print(tunnit, ":", minuutit)
minuutit += 1
tunnit += 1
main()
CSE-A1111
Ohjelmoinnin peruskurssi Y1
16.9.2015
26 / 26