đ Strontium
TĂ€rpit
Format Operator
Pythonin f-string on tehokas tapa formatoida merkkijonoja. Se on ollut kÀytössÀ Python 3.6:sta lÀhtien. F-stringin avulla voit lisÀtÀ muuttujia suoraan merkkijonoon. F-stringin tunnistaa siitÀ, ettÀ merkkijonon alkuun tulee f
-kirjain. Esimerkiksi:
Huomaa, ettÀ yksinkertaisen muuttujan ujuttamisen lisÀksi f-string sallii uskomattoman mÀÀrÀn muotoilua, ja tyypillisen Python-lausekkeen kÀytön. Esimerkiksi:
Voit tutustua tÀhÀn muotoiluun Python f-string cheat sheets -sivuston avulla tai suoraan Python Docs: String > Format String Syntax.
Mukavuus
Visual Studio Coden kÀyttö
Mukavuus-otsikon alla on oletus, ettÀ sinulla on kÀytössÀ Visual Studio Code, Python Extension ja lokaalisti asennettu Python 3.1x. Python voi olla Ubuntun mukana tullut, Python.org-sivustolta ladattu, uv-työkalulla asennettu tai jokin muu. TÀrkeintÀ on, ettÀ Python on lisÀtty kÀyttöjÀrjestelmÀsi PATH:iin ja on tÀten ajettavissa terminaalista komennolla python
tai python3
.
Venv
Warning
Pythonin virtuaaliympÀristöt eivÀt ole maailman helpoin aihe. Tulethan lÀsnÀtunneille paikalle, jotta saat tÀhÀn tukea ja neuvoja!
Kun luot uudet Python-projektin Visual Studio Codessa, sinulla voi olla tarve asentaa joitakin moduuleita. Olet jo aiemmin oppinut, ettÀ Debian-pohjaisessa ympÀristössÀ on dist-packages
-hakemisto, jossa on esimerkiksi requests
-moduuli asennettuna. Jos olet jossakin toisesssa kÀyttöjÀrjestelmÀssÀ tai jakelussa, se voi hyvin puuttua sinulta. TÀssÀ tapauksessa tarvitset virtuaaliympÀristön.
VirtuaaliympÀristö kuulostanee monimutkaiselta, mutta kÀytÀnnön tasolla se on kopio Python-asennuksesta. Luo se uv
:n avulla:
Jos sinulla on uv, kÀytÀ ihmeessÀ sitÀ! Jos ei ole, asenna se. Asennus vaatii yhden komennon ajamisen, joka löytyy Uv uv:n etusivulta. Työkalu toimii Windowsissa, Linuxissa ja macOS:ssÀ samoin tavoin.
# Varmista, ettÀ olet projektisi hakemistossa
$ cd mene/sinun/projektisi/hakemistoon
# Mene ALIHAKEMISTOON python/
$ cd python
# Asenna haluamasi Python
$ uv install 3.12
$ uv pin 3.12
$ uv init --name "skriptiohjelmointi" --bare --app .
# Asenna virtuaaliympÀristöön requests
$ uv add requests
# Aja uv:n hallinnoima Python
$ uv python scripts/hello.py
Tutustu syntyneisiin tiedostoihin, kuten .python-version
ja pyproject.toml
. Kysy opettajalta apua, jos jokin asia askarruttaa.
Jos sinulla on Windowsiin asennettuna Python 3.xx, etkÀ jostain syystÀ saa uv:ta asennettua, voit kÀyttÀÀ Python-osion tehtÀvissÀ venv
-moduulia. Myöhemmin Ansible-osiossa kÀytetÀÀn kuitenkin uv
:ta Linuxissa, joten tee tÀmÀ vain jos ei ole muita vaihtoehtoja!. Jos sinulla on uv
tai mahdollisuus asentaa se, valitse ylhÀÀltÀ uv
-vÀlilehti.
# Varmista, ettÀ olet projektisi hakemistossa
PS> cd mene/sinun/projektisi/hakemistoon
# Mene ALIHAKEMISTOON python/
PS> cd python
# Suositeltu: kiellÀ pip:n kÀyttö virtuaaliympÀristön ulkopuolella
PS> pip3 config set global.require-virtualenv true
# Luo virtuaaliympÀristö
PS> python3 -m venv .venv
# Aktivoi virtuaaliympÀristö
PS> .venv\Scripts\Activate.ps1
# Asenna haluamasi moduulit
(.venv) PS> pip install requests
# Aja Python
(.venv) PS> python scripts/hello.py
# Deaktivoi virtuaaliympÀristö
(.venv) PS> deactivate
Muista Git Ignore!
EthÀn unohda lisÀtÀ kyseistÀ hakemistoa .gitignore
-tiedostoon, jotta se ei pÀÀdy versionhallintaan! Se on kopio Pythonista, joten se sisÀltÀÀ satoja binÀÀritiedostoja, jotka eivÀt todellakaan kuulu versionhallintaan. Kukin kÀyttÀjÀ luo oman virtuaaliympÀristönsÀ itse.
LisÀÀ siis seuraava rivi .gitignore
-tiedostoon:
Tarkista, ettÀ tiedostoja ei nÀy versionhallinnassa komennolla git status -u
.
Huomaa, ettÀ on kaksi eri asiaa: kÀyttÀÀ virtuaaliympÀristöÀ shell-istunnossa ja Visual Studio Coden GUI:ssa. Visual Studio Code yleensÀ havaitsee, jos luot virtuaaliympÀristön, mutta ei aina. Visual Studio Code saattaa myös jatkossa aktivoida sen automaattisesti shell-istuntoon, mutta tÀmÀ riippuu asetuksesta:
{
// ...
"python.terminal.activateEnvironment": false,
// ...
}
Sen sijaan VS Coden GUI-editorin, eli ei siis integroidun terminaalin, kÀyttÀmÀ Python on valittavissa painamalla F1
ja kirjoittamalla Python: Select Interpreter
. YleensÀ VS Code avaa alla nÀkyvÀn (ks. Kuva 1) pop-up -ikkunan ruudun oikeaan alalaitaan kun olet luonut virtuaaliympÀristön. Jos tÀmÀ popup menee sinulta ohi syystÀ tai toisesta, voit valita Workspace-kohtaisen virtuaaliympÀristön painamalla F1
ja kirjoittamalla Python: Select Interpreter
. KenttÀÀn voi kirjoittaa relatiivisen polun projektin uudesta esimerkiksi nÀin: ${workspaceFolder}/python/.venv/
. TÀmÀ polun kÀsin kirjoittaminen on tarpeen vain, jos executable on jossakin muualle kuin avoinna olevan kansion juuressa (kuten python/.venv
eikÀ .venv/
).
Kuva 1: Visual Studio Code ilmoittaa, ettÀ se on havainnut uuden virtuaaliympÀristön, ja tarjoaa sinun valita sen kyseistÀ worskpacea varten. Klikkaa Yes.
Intellisense
Aivan kuten PowerShell, myös Python on hyvin vahvasti object-oriented -kieli. TÀmÀ tarkoittaa, ettÀ Pythonissa kaikki on objekteja, ja objekteilla on metodeja ja ominaisuuksia. Olet jo kokeillut samaa ominaisuutta PowerShellin kanssa, mutta kokeile uusiksi Pythonin kanssa. Luo esimerkiksi seuraava skripti:
Kun lisÀÀt sanan name
perÀÀn vielÀ pisteen, aukeaa lista objektin metodeista ja ominaisuuksista. Kokeile esimerkiksi name.upper()
. Jos lista ei aukea, paina Ctrl+Space. Huomaa, ettÀ IntelliSense kÀyttÀÀ sitÀ Python-versiota, joka on valittu Visual Studio Codessa. TÀmÀ neuvotaan yllÀ.
đ macOS
Sama pikanÀppÀin on Fn+Ctrl+Space
Run Selection
Joskus voi olla tarpeen ajaa valittu koodinpÀtkÀ lokaalin koneen terminaalissa. Kenties haluat nopeasti kokeilla, kuinka keskellÀ pitkÀÀ skriptiÀ mÀÀritelty funktio toimii ajamatta muuta koodia? TÀmÀ onnistuu Visual Studio Codessa valitsemalla koodinpÀtkÀ ja painamalla Shift+Enter. Vaiheoehtoinen tapa on context menu. Klikkaa hiiren oikealla korvalla valittuja koodirivejÀ, valitse Run Python > ja Run Selection/Line in Python Terminal.
Kuva 2: SkripistÀ on valittuna vain yksi funktio, function_i_wanna_test
, ja se ajetaan terminaalissa.
Kun ajat koodin nÀin, huomaat, ettÀ alle Terminal-kohtaan ilmestyy uusi Python-niminen terminaali, jossa koodi suoritetaan REPL-tilassa. TÀmÀ on vastaava tapa kuin ajaa aiemmin nÀkemÀsi python -i scripts/some.py
, mutta voit valita juuri ne rivit, jotka haluat suoritettavaksi. Kuten alla olevasta snippetistÀ nÀet, funktio on jatkossa kutsuttavissa kyseisessÀ terminaalissa.
>>> function_i_wanna_test([1,2,3,4,5,6], 3)
([1, 2], [3, 4, 5, 6])
TehtÀvÀt
TehtÀvÀ: Arvaa numero
Luo ohjelma, joka generoi luvun vÀliltÀ 1-1000 ja pyytÀÀ kÀyttÀjÀÀ arvaamaan sen. Ohjelma antaa vihjeen, onko arvattu luku suurempi vai pienempi kuin generoitu luku. Ohjelma lopettaa, kun kÀyttÀjÀ arvaa oikein. Olet tehnyt ohjelman jo aiemmin (Bash ja PowerShell), joten voit lainata sieltÀ logiikan.
$ ./runpy.py scripts/arvaaluku.py
Arvaa luku vÀliltÀ 1-1000.
Muu syöte kuin positiviinen kokoluku poistuu ohjelmasta.
SyötÀ arvaus:
9
đ Luku on pienempi kuin 9.
SyötÀ arvaus:
7
đ Luku on suurempi kuin 7.
SyötÀ arvaus:
8
đ Oikein! Arvasit luvun 8. (Peliaika: 0h 4m 18s)
Varmista, ettÀ pelaaja voi halutessaan lopettaa pelin. Minun toteutuksessa mikÀ tahansa muu syöte kuin kokonaisluvuksi parsittava syöte lopettaa pelin (esim. exit tai tyhjÀ merkkijono).
â ïž TĂRKEĂĂ
Kirjoita ohjelman input()
ilman promptia. Anna prompti erillisellÀ print-komennolla. TÀmÀ helpottaa kurssin myöhempÀÀ tehtÀvÀÀ, jossa rakennamme skriptin, joka pelaa peliÀ meidÀn puolestamme. Eli siis:
TehtÀvÀ: Reminder
TÀmÀn pitÀisi olla sinulle jo tuttua. Luo kaksi ohjelmaa, jotka toimivat yhdessÀ. Toinen luo, toinen nÀyttÀÀ muistiinpanoja. LisÀksi on olemassa apuohjelma, joka lisÀÀ nÀmÀ PATH:iin.
install_reminder.py
- LisÀÀ
remind
jaremember
symboliset linkit PATH:iin.
- LisÀÀ
remember
- Kysyy kÀyttÀjÀltÀ muistutuksia, jotka tallennetaan
~/.reminder
-tiedostoon. - TyhjÀ syöte lopettaa ohjelman.
- Formaatti:
[YYYY-MM-DD HH:MM] Muistutus
- Kysyy kÀyttÀjÀltÀ muistutuksia, jotka tallennetaan
remind
- Tulostaa muistutukset
- Antaa mahdollisuuden poistaa muistutuksia TUI-kÀyttöliittymÀllÀ.
KÀytÀ TUI:n (Text User Interface) luomiseen curses
-moduulia. Moduuli tulee Pythonin mukana Unix-like -jÀrjestelmissÀ, joten sitÀ ei tarvitse asentaa erikseen.
Lopulta kÀyttö nÀyttÀÀ tÀltÀ, kun komennot ajetaan kontin sisÀllÀ (python runpy.py --bash
):
# python scripts/install_reminder.py
Created symbolic link: /usr/local/bin/remind -> /app/scripts/remind.py
Created symbolic link: /usr/local/bin/remember -> /app/scripts/remember.py
# remember
Enter a reminder: Learn Bash
Enter a reminder: Learn PowerShell
Enter a reminder: Learn Python
Enter a reminder: Eat spam
Enter a reminder:
Goodbye đ! To view reminders, run: remind
# remind
ks. kuva alta

Kuva 3: Muistutusten lisÀÀminen ja poistaminen TUI:n avulla.
Executable
Huomaa, ettÀ sinun tulee tehdÀ skripteistÀ suoritettavia host-koneellasi, sillÀ kontissa kyseinen volume on read-only. Jos teet tÀtÀ kurssin osuutta Windowsista kÀsin, etkÀ voi tehdÀ tÀtÀ, luo skripti siten, ettÀ se luo symbolisen linkin sijasta aliaksen:
Kuinkahan tÀmÀ onnistuu Pythonissa?
Opettajan versio
Alla on opettajan versio siten, ettÀ osa riveistÀ on jemmattu. Muista, ettÀ tÀllÀ kurssilla koodin ymmÀrtÀminen on tÀrkeÀÀ. Jos opettaja kysyy sinulta, mitÀ jokin rivi tekee, osaatko vastata?
#!/bin/env python3
import curses
from pathlib import Path
TARGET = Path("~/.reminder").expanduser()
def load_reminders() -> list[str]:
pass
def save_reminders(reminders: list[str]):
pass
def filter_and_save(reminders: list[str], sel: set[int]):
kept_reminders = [
rem for idx, rem in enumerate(reminders) if idx not in sel
]
save_reminders(kept_reminders)
def draw_menu(stdscr: curses.window, rem: list[str], curr: int, sel: set[int]):
stdscr.clear()
stdscr.addstr(
0, 2, "Press SPACE to mark as done, Q to save and quit", curses.A_BOLD
)
for idx, reminder in enumerate(rem):
# Highlight the current row
attr = curses.A_REVERSE if idx == curr else curses.A_NORMAL
# Add checkboxes
if idx in sel:
button = "[X] "
else:
button = "[ ] "
stdscr.addstr(idx + 2, 2, button + reminder, attr)
def reminder_app(stdscr: curses.window):
curses.curs_set(0) # Hide text cursor
stdscr.keypad(True) # Enable arrow keys
stdscr.clear()
reminders = load_reminders()
if not reminders:
raise SystemExit("No reminders found!")
selected = set()
current_row = 0
while True:
draw_menu(stdscr, reminders, current_row, selected)
# Get event
key = stdscr.getch()
if key == curses.KEY_UP and current_row > 0:
current_row -= 1
elif key == curses.KEY_DOWN and current_row < len(reminders) - 1:
current_row += 1
elif key == curses.KEY_RIGHT:
selected.add(current_row)
elif key == curses.KEY_LEFT:
selected.remove(current_row)
elif key in (ord("Q"), ord("q")):
filter_and_save(reminders, selected)
break
if __name__ == "__main__":
curses.wrapper(reminder_app)
TehtÀvÀ: breakpoint()
Koska kÀytÀmme Visual Studio Codea, voimme kÀyttÀÀ sen interaktiivista debuggeria CLI-pohjaisen Pdb:n (Python Debugger) sijasta. TÀmÀn kÀyttö esitellÀÀn lÀsnÀtunneilla. On kuitenkin suositeltavaa kokeilla Pdb:tÀ lyhyesti ihan sivistyksen tÀhden. Vastaavia työkaluja löytyy myös muista kielistÀ, kuten Pdb:n esikuva GDB, joka voi kÀyttÀÀ useissa kielissÀ: C, C++, Rust ja moni muu.
Yksi tapa aktivoida Pdb on sijoittaa skriptiin alla olevassa code snippetissÀ oleva rivi. Rivin voi tarpeen mukaan ujuttaa useisiin paikkoihin, jolloin debuggeri pysÀhtyy jokaisen rivin kohdalla.
Koodi pysÀyttÀÀ suorituksen kyseiseen kohtaan ja avaa Pdb:n. TÀssÀ tilassa ei ole tarkoitus kirjoittaa interaktiivisesti Pythonia vaan tarkkailla muuttujien arvoja esimerkiksi looppia ajettaesa.
#!/usr/bin/env python3
n = 5
counter = 0
for i in range(n):
breakpoint()
counter += 1
$ ./runpy.py scripts/breakpoint_practice.py
(Pdb) p counter
0
(Pdb) continue
> /app/scripts/breakpoint_practice.py(8)<module>()
-> counter += 1
(Pdb) p counter
1
Debuggerissa toimivat muiden muassa seuraavat komennot [^pdb]:
[^pdb] Python Docs. The Python Debugger. https://docs.python.org/3/library/pdb.html
Peruskomennot
Komento | Kuvaus |
---|---|
`h(elp) | NÀytÀ ohjeet (eli kaikki nÀmÀ komennot) |
`q(uit) | Poistu debuggerista |
c(ontinue) |
Jatka suoritusta seuraavaan breakpointtiin asti |
n(ext) |
Suorita seuraava rivi (astu funktiokutsun yli) |
s(tep) |
Astu funktiokutsuun |
r(eturn) |
Suorita loppuun nykyinen funktio |
Tarkastelu
Komento | Kuvaus |
---|---|
l(ist) |
NÀytÀ koodi breakpointin lÀheisillÀ riveillÀ |
p expr |
Tulosta lausekkeen arvo |
pp expr |
Tulosta lausekkeen arvo (prettify) |
whatis |
NÀytÀ lausekkeen tyyppi |
Lauseke (engl. expression) on usein muuttuja, mutta voi olla myös esimerkiksi funktio tai moduuli.
TehtÀvÀ: IP Address
Kirjoita Python-skripti, joka:
- KÀyttÀÀ built-in kirjastoa
ipaddress
. - Kysyy kÀyttÀjÀltÀ IP-osoitteen CIDR-notaatiolla (esim.
192.168.0.12/24
). - Tulostaa seuraavat sekÀ desimaali- ettÀ binÀÀrimuodossa:
- Verkon osoite
- Verkon maski
- EnsimmÀinen host ip
- Viimeinen host ip
- Broadcast ip
Alla esimerkki kÀytöstÀ. Huomaa, ettÀ tulosteen ei tarvitse olla merkistÀ merkkiin muotoiltu samalla tavalla.
./runpy.py scripts/cidr_range.py
Enter a network (CIDR notation): 10.0.2.42/23
Label IP Address Binary
---------------------------------------------------------------------
Network: 10.0.2.0 00001010 00000000 00000010 00000000
Netmask: 255.255.254.0 11111111 11111111 11111110 00000000
First IP: 10.0.2.1 00001010 00000000 00000010 00000001
Last IP: 10.0.3.254 00001010 00000000 00000011 11111110
Broadcast: 10.0.3.255 00001010 00000000 00000011 11111111
Host-ip verkon osoitteeksi
Verkon osoite on se osoite, joka on ensimmÀinen mahdollinen osoite kyseisessÀ verkossa. KÀyttÀjÀ saattaa ajatuksissaan antaa osoitteen, joka ei ole verkon vaan yksittÀisen laitteen ip, kuten yllÀ olevassa esimerkissÀ (192.168.0.12/24
). Saat muunnettua tÀmÀn verkon osoitteeksi kÀyttÀmÀllÀ network_address
-metodin parametrina strict=False
.
MissÀ IP:t?
Huomaa, ettÀ network.broadcast_address
palauttaa IPv4Network-olion. Kenties keksit kÀyttöÀ seuraaville:
network.broadcast_address
list(network.hosts())
palauttaalist[IPv4Address]
sisÀltÀen vain hostitint(some_ipv4)
palauttaa desimaalimuodossa olevan ip:n
IP neljÀksi oktetiksi
MikÀ tahansa numero on helppo tulostaa 32-bittiÀ pitkÀnÀ binÀÀrinÀ. Se onnistuu f-stringin avulla ({int(ip):032b}
). Sen tulostaminen 4 eri osassa, eli oktetissa, vaatii hieman koodia, mutta parantaa tulosteen luettavuutta. TÀmÀn voi luonnollisesti tehdÀ monella tapaa. Alla helppolukuinen tapa:
def ip2bin(ip: ipaddress.IPv4Address) -> str:
"""
Convert an IPv4 address to binary format with whitespace between octets, like:
10000001 10000001 10000001 10000001
"""
bit_32 = f"{int(ip):032b}"
octets = []
for i in range(0, 32, 8):
octet = bit_32[i : i + 8]
octets.append(octet)
return " ".join(octets)