Ohjelmoinnin peruskurssi Y1 CSE-A1111 5.10.2015 CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 1 / 36
Mahdollisuus antaa luentopalautetta Goblinissa vasemmassa reunassa olevassa valikossa on valinta Luentopalaute. Tätä kautta on mahdollisuus antaa nimettömänä palautetta luennosta. Jos jokin asia on jäänyt palautteen perusteella epäselväksi, palataan siihen mahdollisuuksien mukaan seuraavalla luennolla. CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 2 / 36
Oppimistavoitteet: tämän luennon jälkeen Tunnet lisää erilaisia tapoja käyttää listoja Python-ohjelmissa. Osaat käyttää totuusarvoja sisältäviä listoja. Tunnet erilaisia tapoja käsitellä merkkijonoja. Osaat esimerkiksi käsitellä käyttäjän antamaa syötettä monipuolisemmin kuin aikaisemmin. CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 3 / 36
Alilistat Listasta voi ottaa helposti alilistoja (alkuperäisen listan osia): >>> lista = [2, 4, 6, 8, 10, 12, 14, 16] >>> alilista = lista[2:5] >>> print(alilista) [6, 8, 10] Kaksoispisteen jälkeen annettua indeksia ei enää oteta mukaan. Ensimmäinen tai viimeinen indeksi voidaan myös jättää merkitsemättä, jolloin alilistaan otetaan alkiot listan alusta lähtien tai listaan loppuun asti: >>> lista[:5] [2, 4, 6, 8, 10] >>> lista[5:] [12, 14, 16] Negatiiviset indeksit tarkoittavat alkioita listan lopusta lähtien: >>> lista[:-1] [2, 4, 6, 8, 10, 12, 14] CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 4 / 36
Lisäys listaan Listan loppuun voi lisätä uuden alkion append-metodilla: >>> lista = [2, 4, 6, 8, 10, 12, 14, 16] >>> lista.append(-3) >>> print(lista) [2, 4, 6, 8, 10, 12, 14, 16, -3] Sijoituskäsky ei lisää listaan uutta alkota, vaan se korvaa vanhan alkion uudella: >>> lista[3] = -5 >>> print(lista) [2, 4, 6, -5, 10, 12, 14, 16, -3] Sen sijaan metodilla insert voi lisätä halutulle indeksille uuden alkion. Lisäyspaikan jälkeen tulevia alkioita siirretään listan loppuun päin: >>> lista.insert(3, 22) >>> print(lista) [2, 4, 6, 22, -5, 10, 12, 14, 16, -3] CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 5 / 36
Alkion poistaminen listasta Metodi remove poistaa ensimmäisen alkion, jolla on parametrina annettu arvo: >>> print(lista) [2, 4, 6, 22, -5, 10, 12, 14, 16, -3] >>> lista.remove(22) >>> print(lista) [2, 4, 6, -5, 10, 12, 14, 16, -3] Operaattori del poistaa alkion halutulta indeksiltä: >>> print(lista) [2, 4, 6, -5, 10, 12, 14, 16, -3] >>> del lista[5] >>> print(lista) [2, 4, 6, -5, 10, 14, 16, -3] CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 6 / 36
Listan järjestäminen ja kääntäminen Metodi sort järjestää listan: >>> lista.sort() >>> print(lista) [-5, -3, 2, 4, 6, 10, 14, 16] Metodi reverse kääntää listan järjestyksen päinvastaiseksi. >>> lista.reverse() >>> print(lista) [16, 14, 10, 6, 4, 2, -3, -5] Funktio sorted tekee listasta kopion ja järjestää tämän kopion. Alkuperäinen lista jää entiselleen: >>> lista2 = sorted(lista) >>> print(lista2) [-5, -3, 2, 4, 6, 10, 14, 16] >>> print(lista) [16, 14, 10, 6, 4, 2, -3, -5] CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 7 / 36
Listojen yhdistäminen Kaksi listaa voidaan yhdistää käyttämällä operaattoria +: >>> lista1 = [1, 2, 3] >>> lista2 = [4, 5, 6] >>> yhteislista = lista1 + lista2 >>> print(yhteislista) [1, 2, 3, 4, 5, 6] CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 8 / 36
Totuusarvoja sisältävä lista Lista voi sisältää myös bool-tyyppisiä arvoja eli arvoja True ja False Seuraavassa esimerkkiohjelmassa on käytetty tällaista listaa kuvaamaan jonkin salin (esim. elokuvateatteri, teatteri tai konserttisali) varaustilannetta. Oletetaan, että paikat on numeroitu nollasta alkaen. Listassa on indeksillä i arvo True, jos paikka on varattu, ja arvo False, jos paikka on vapaa. Ohjelmassa on funktiot halutun paikan varaamiseen, sen selvittämiseen, onko määrätty paikka vapaa, kaikkien vapaiden paikkojen selvittämiseen sekä varattujen paikkojen määrän selvittämiseen. Ohjelmassa on vain lyhyt esimerkkipääohjelma näyttämään sitä, miten eri funktioita voidaan kutsua. Jotta järjestelmää voisi oikeasti käyttää, tarvittaisiin selvästi pitempi käyttöliittymäohjelma. CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 9 / 36
Paikanvarausohjelma def varaa_paikka(varatut, paikka): if 0 <= paikka < len(varatut) and not varatut[paikka]: varatut[paikka] = True return True else: return False def onko_vapaa(paikkalista, nro): if 0 <= nro < len(paikkalista): return not paikkalista[nro] else: return False CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 10 / 36
Paikanvarausohjelma, jatkoa def kerro_vapaat_paikat(varauslista): vapaiden_lista = [] for i in range(len(varauslista)): if not varauslista[i]: vapaiden_lista.append(i) return vapaiden_lista def montako_varattu(varaukset): varattuja = 0 for alkio in varaukset: if alkio: varattuja += 1 return varattuja CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 11 / 36
Paikanvarausohjelma, jatkoa def main(): PAIKKAMAARA = 10 paikka_varattu = [False] * PAIKKAMAARA for i in range(5): paikkanro = int(input("mika paikka varataan? ")) if varaa_paikka(paikka_varattu, paikkanro): print("paikan varaus onnistui!") else: print("varaus ei onnistunut.") tutkittava = int(input("anna paikan numero: ")) if onko_vapaa(paikka_varattu, tutkittava): print("paikka", tutkittava, "on vapaa.") else: print("paikka", tutkittava, "ei ole vapaa.") CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 12 / 36
Paikanvarausohjelma, jatkoa main() print("vapaat paikat:") print(kerro_vapaat_paikat(paikka_varattu)) print("paikkoja on varattu {:d} / {:d}.".format( montako_varattu(paikka_varattu), len(paikka_varattu))) CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 13 / 36
Välitehtävä Lisää edellä esitettyyn paikanvarausohjelmaan funktio varaa_ensimmainen_vapaa, joka varaa ensimmäisen vapaan paikan. Funktio palauttaa varatun paikan numeron tai arvon -1, jos kaikki paikat on jo varattu. Jos aikaa jää, mieti, miten funktiota voi kutsua pääohjelmassa niin, että siellä joko tulostetaan varatun paikan numero tai vaihtoehtoisesti tieto siitä, että vapaita paikkoja ei enää ole. CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 14 / 36
Merkkijonot Merkkijonojen avulla ohjelmassa voi esittää tekstitietoa, esim. nimiä, osoitteita ja erilaisia tunnuksia. Merkkijonon tyyppi Pythonissa on str. Yksittäisiä merkkejä varten ei ole omaa tyyppiä, vaan ne ovat yhden merkin pituisia merkkijonoja. Merkkijono esitetään yksin- tai kaksinkertaisten lainausmerkkien avulla. mjono = appelsiini mjono = "appelsiini" Useammalle riville jatkuva merkkijono kirjoitetaan kolmen lainausmerkin sisään. pitkajono = """Tama merkkijono sisaltaa useamman kuin yhden rivin""" CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 15 / 36
Merkkijonojen käsittely Merkkijonoja voidaan käsitellä monessa tapauksessa samalla tavalla kuin listoja, esim. >>> sana = "sitruuna" >>> print(sana[3]) r Olennainen ero: merkkijonon sisältöä ei voi muuttaa sen jälkeen, kun merkkijono on luotu, esim. >>> sana[3] = a Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: str object does not support item assignment CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 16 / 36
Merkkijonon läpikäynti Merkkijonon merkit voi käydä läpi for-käskyn avulla samalla tavalla kuin listan alkiot: >>> mjono = "matti" >>> for merkki in mjono:... print(merkki)... m a t t i CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 17 / 36
Alimerkkijonot Merkkijonosta voi ottaa myös alimerkkijonoja samaan tapaan kuin listoista alilistoja: >>> mjono = "appelsiini" >>> print(mjono[2:5]) pel >>> print(mjono [:4]) appe >>> print(mjono [:-1]) appelsiin CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 18 / 36
Merkkijonon pituus ja merkin esiintymisen tutkiminen Merkkijonon pituuden saa selville funktiolla len. >>> mjono = "appelsiini" >>> print(len(mjono)) 10 Operaattorin in avulla voi tutkia, esiintyykö merkki merkkijonossa. >>> print("i" in mjono) True Operaattorin in avulla voi myös tutkia, esiintyykö pitempi merkkijono osana toista. >>> print("else" in mjono) False >>> print("elsi" in mjono) True CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 19 / 36
Merkin esiintymiskohta merkkijonossa Metodin index avulla voidaan hakea parametrina annetun merkin ensimmäinen esiintymispaikka merkkijonosta: >>> mjono = "appelsiini" >>> print(mjono.index("i")) 6 Saman metodin avulla voidaan hakea myös pitempää merkkijonoa: >>> print(mjono.index("lsi")) 4 Ohjelma kaatuu, jos haettua merkkijonoa ei löydy : >>> print(mjono.index("lse")) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: substring not found CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 20 / 36
Sijoitus merkkijonomuuttujaan Merkkijonon sisältöä ei voi muuttaa sen jälkeen, kun merkkijono on luotu. Voidaan kuitenkin tehdä uusi merkkijono ja sijoittaa se arvoksi vanhalle muuttujalle: >>> mjono = "mansikka" >>> print(mjono) mansikka >>> mjono = "mustikka" >>> print(mjono) mustikka CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 21 / 36
Uusi merkkijono vanhan avulla Uusi merkkijono voi kuitenkin riippua jotenkin vanhasta merkkijonosta. Metodi upper luo uuden merkkijonon, joka sisältää muuten samat merkit kuin vanha merkkijono, mutta kaikki pienet kirjaimet on muutettu isoiksi: >>> mjono = "mustikka" >>> mjono = mjono.upper() >>> print(mjono) MUSTIKKA Metodi lower luo uuden merkkijonon, joka sisältää muuten samat merkit kuin vanha merkkijono, mutta kaikki isot kirjaimet on muutettu pieniksi: >>> print(mjono) MUSTIKKA >>> mjono = mjono.lower() >>> print(mjono) mustikka CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 22 / 36
Merkkijonojen liittämiset Useampi merkkijono voidaan liittää peräkkäin +-operaattorilla. >>> etunimi = "Matti" >>> sukunimi = "Virtanen" >>> kokonimi = etunimi + " " + sukunimi >>> print(kokonimi) Matti Virtanen Jos merkkijonoon halutaan liittää muuntyyppisten muuttujien arvoja, pitää ensin suorittaa tyypinmuunnos str-operaattorilla. >>> tunteja = 50 >>> tuntip = 12.5 >>> palkka = tunteja * tuntip >>> tulosrivi = str(tunteja) + " h * " + str(tuntip) + \... " eur / h = " + str(palkka) >>> print(tulosrivi) 50 h * 12.5 eur / h = 625.0 CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 23 / 36
Merkkijonojen monistaminen Operaattorin * avulla voidaan tehdä merkkijono, joka sisältää pienemmän merkkijonon monta kertaa. Rivinvaihtomerkin saa tarvittaessa mukaan lisäämällä merkkijonoon erikoismerkin "\n": >>> merkit = "*!*" >>> rivi = 5 * merkit >>> print(rivi) *!**!**!**!**!* >>> rivit = 3 * (rivi + "\n") >>> print(rivit) *!**!**!**!**!* *!**!**!**!**!* *!**!**!**!**!* CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 24 / 36
Erikoismerkkejä Merkkijonoihin on mahdollista liittää erikoismerkkejä (engl. escape characters), jotka aiheuttavat tulostuksessa esimerkiksi rivinvaihdon tai kursorin siirron seuraavaan tabulointikohtaan. Tärkeimpiä erikoismerkkejä: \n rivinvaihto \t tabulaattori \ yksinkertainen lainausmerkki \" kaksinkertainen lainausmerkki \\ yksi kenoviiva CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 25 / 36
Tyhjien merkkien poisto syötteen alusta ja lopusta Usein halutaan poistaa käyttäjän syötteestä käyttäjän mahdollisesti vahingossa alkuun tai loppuun kirjoittamat ns. tyhjät merkit (välilyönnit, tabuloinnit, rivinvaihdot). Tämä on helppo tehdä metodin strip avulla: >>> syote = input("anna tekstia.\n") Anna tekstia. kirjoitetaan jotain >>> print("*{:s}*".format(syote)) * kirjoitetaan jotain * >>> muutettu_syote = syote.strip() >>> print("*{:s}*".format(muutettu_syote)) *kirjoitetaan jotain* Jos tyhjät merkit halutaan poistaan vain merkkijonon alusta tai lopusta, voidaan käyttää metodeita lstrip tai rstrip. CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 26 / 36
Merkkijonon jakaminen Monesti on tarve jakaa merkkijono osiin jonkun merkin (esimerkiksi välilyönnin kohdalta). Esimerkki: halutaan erottaa samalla rivillä annettu etunimi ja sukunimi tai sana ja sen käännös toiselle kielelle toisistaan. Merkkijono voidaan jakaa metodilla split. Se palauttaa listan, joka sisältää jaetun merkkijonon eri osat. Oletusarvoisesti split-metodi jakaa merkkijonon välilyönnin kohdalta, mutta metodille voidaan antaa parametrina joku muu merkki, jonka kohdasta jako tehdään. Jaossa käytetty merkki ei tule mukaan mihinkään osaan. CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 27 / 36
Merkkijonon jakaminen, esimerkkejä >>> teksti = "Pitka teksti, joka sisaltaa monta eri sanaa." >>> osat = teksti.split() >>> print(osat) [ Pitka, teksti,, joka, sisaltaa, monta, eri, sanaa. ] >>> sanarivi = "kirja=book" >>> kaannokset = sanarivi.split("=") >>> print(kaannokset) [ kirja, book ] CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 28 / 36
Välitehtävä Käyttäjältä luetaan merkkijono, joka sisältää yhden kilpailijan nimen sekä tämän kilpailijan pisteet kahdelta eri kilpailukierrokselta. Eri tiedot on erotettu toisistaan kauttaviivalla /. Kirjoita ohjelman osa, joka laskee kilpailijan yhteispisteet (molempien kierrosten pisteet yhteensä). Tämän jälkeen ohjelman pitää tulostaa kilpailijan nimi ja hänen yhteispisteensä. Esimerkki käyttäjän antamasta rivistä: Teemu Teekkari/25/15 CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 29 / 36
Merkkijonojen vertailu Merkkijonojen sisältöjä voi verrata toisiinsa vertailuoperaattoreilla ==,!=, <=, >=, < ja >. Kun katsotaan, onko toinen merkkijono suurempi kuin toinen, verrataan merkkejä keskenään merkkijonojen alusta lähtien. Järjestyksen määrää kirjainten arvo käytetyssä merkkikoodausjärjestelmässä mitä lukuarvoa kukin kirjain vastaa. Käytännössä koodit noudattavat muuten aakkosjärjestystä, mutta isot kirjaimet ovat ennen pieniä ja skandinaaviset aakkoset eivät ole keskenään oikeassa järjestyksessä. CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 30 / 36
Esimerkkejä merkkijonojen vertailuista >>> nimi1 = "matti" >>> nimi2 = "teppo" >>> nimi1 == nimi2 False >>> >>> nimi1 < nimi2 True >>> >>> nimi3 = "Teppo" >>> nimi2 == nimi3 False >>> >>> nimi3 < nimi2 True CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 31 / 36
Esimerkkejä merkkijonojen vertailuista, jatkoa >>> nimi1 = "matti" >>> nimi4 = "matilda" >>> nimi1 < nimi4 False CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 32 / 36
Esimerkki: lämpötilamuunnos Seuraava esimerkkiohjelma muuttaa käyttäjän antamia lämpötiloja fahrenheit-asteista celsius-asteiksi tai päinvastoin käyttäjän valinnan mukaan. Merkkijonojen vertailulla selvitetään, kumpaan suuntaan käyttäjä haluaa tehdä muunnoksen ja sen mukaan kutsutaan oikeaa funktiota. Lisäksi vertailun avulla selvitetään, haluaako käyttäjä tehdä uuden muunnoksen. Käyttäjän syötteet muutetaan kokonaan isoiksi tai pieniksi kirjaimiksi, jotta niiden ero ei vaikuttaisi vertailun tulokseen. CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 33 / 36
Lämpötilamuunnos: koodi def muunna_celsiuksiksi(fahr_asteet): celsius_asteet = (fahr_asteet - 32) * 5.0 / 9.0 return celsius_asteet def muunna_fahrenheiteiksi(cel_asteet): fahrenheit_asteet = 9.0/5.0 * cel_asteet + 32 return fahrenheit_asteet CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 34 / 36
Lämpötilamuunnos: koodi jatkuu def main(): jatko = "kylla" while jatko!= "ei": rivi = input("anna lampotilan yksikko (C/F): ") yksikko = rivi.upper() if yksikko == "C": asteet = float(input("lampo celsiuksina: ")) fahrenheit = muunna_fahrenheiteiksi(asteet) print(asteet, "C on", fahrenheit, "F.") elif yksikko == "F": asteet = float(input("lampo fahrenheiteina: ")) celsius = muunna_celsiuksiksi(asteet) print(asteet, "F on", celsius, "C.") CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 35 / 36
Lämpötilamuunnos: koodi jatkuu main() else: print("virheellinen yksikko, oikea on C tai F") rivi = input("haluatko jatkaa (kylla/ei)? ") jatko = rivi.lower() CSE-A1111 Ohjelmoinnin peruskurssi Y1 5.10.2015 36 / 36