Lektion 4 · Cirka 45 min genomgång

Bibliotek
Libraries

Pythonprogram behöver inte börja från noll. Med moduler och packages kan du återanvända väl avgränsad kod, arbeta med kommandoradsargument och hämta strukturerade data från webbtjänster.

Modulen random ingår i Pythons standardbibliotek. Punktnotationen visar att funktionen choice hämtas ur modulens namnrymd.

slumpa.pyPython
import random

mynt = random.choice(["krona", "klave"])
print(mynt)
Resultatkrona

Före genomgången

Se filmen och kontrollera din aktiva miljö

Harvards lecture 4 heter Libraries. Se filmen före lektionen. Kontrollera sedan att VS Code använder samma Anaconda- eller conda-miljö i editorn, terminalen och Jupyter-kärnan.

1

Se lecture 4

Notera skillnaden mellan kod som redan följer med Python och kod som först måste installeras.

Öppna Harvard vecka 4 ↗
2

Skapa en mapp

Skapa lektion_04 i kursmappen och öppna den i VS Code.

3

Kontrollera Python

Kör python --version och python -m pip --version i VS Codes terminal. Sökvägarna ska höra till den miljö du valt.

En sammanhängande verktygskedja

VS Codes valda Pythoninterpreter styr vanliga Pythonfiler. Jupyter använder sin valda kernel. Terminalen använder den miljö som är aktiverad där. Kontrollera alla tre när ett installerat package inte går att importera.

Dagens karta

Från lokal modul till webbtjänst

Varje del utökar vad programmet kan göra, men kräver också att du vet var koden och datan kommer ifrån.

standardbibliotekföljer med Pythonpackageinstalleras i miljönAPIdata över nätverketegen moduldin återanvändbara kod
01

Exakta begrepp

Modul, package och library betyder inte samma sak

Python organiserar återanvändbar kod i moduler och packages. Ordet library, på svenska bibliotek, används mer informellt om en samling kod som erbjuder ett användbart gränssnitt.

Modul

En importerbar kodenhet

En enkel modul är ofta en fil som random.py eller sayings.py. Den kan innehålla funktioner, variabler, klasser och satser. Filnamnet utan .py är normalt modulnamnet.

Package

En strukturerad modulnamnrymd

Ett Python-package kan samla flera moduler och underpackages, exempelvis package.submodule. På PyPI publiceras installerbara distributioner som i sin tur kan innehålla ett eller flera packages och moduler.

Tre vanliga ursprung

Standardbiblioteket
Moduler som distribueras med Python, exempelvis random, statistics, fractions, json och sys. De importeras utan separat installation.
Tredjepartskod
Packages som utvecklas utanför Pythonprojektet och installeras i en viss miljö, exempelvis emoji, pyfiglet, inflect och requests.
Egen kod
Dina egna .py-filer kan importeras som moduler när Python hittar dem i sin sökväg.
sayings.pymodulfilimport sayingsmodulnamnsayings.hello()funktion i modulen
Installationsnamn och importnamn kan skilja sig

Det namn som används med pip beskriver distributionen på PyPI. Koden importerar ett modul- eller packagenamn. Kontrollera alltid projektets dokumentation i stället för att gissa.

02

Ladda och namnge kod

import bestämmer vilka namn som blir tillgängliga

En namnrymd, på engelska namespace, är en koppling mellan namn och objekt. Importformen avgör om du använder modulens namn som prefix eller för in ett enskilt namn direkt i den aktuella namnrymden.

Tydligt ursprung

import random

modulimport.pyPython
import random

sida = random.choice([1, 2, 3, 4, 5, 6])

Namnet random binds till modulobjektet. Punktnotationen visar var choice kommer ifrån och minskar risken för namnkonflikter.

Direkt namn

from random import choice

namnimport.pyPython
from random import choice

sida = choice([1, 2, 3, 4, 5, 6])

Funktionen binds direkt till namnet choice. Koden blir kortare men ursprunget syns inte vid varje anrop.

alias.pyPython
import statistics as stats

varden = [10, 15, 20]
print(stats.mean(varden))
Resultat15

Ett alias är ett lokalt namn

as stats binder modulen till namnet stats i denna fil. Modulen ändrar inte namn globalt. Alias är lämpliga när en etablerad konvention finns eller när originalnamnet är opraktiskt långt.

from modul import * för in ett okänt antal namn och kan skriva över namn du redan använder. Formen gör det också svårt att se var en funktion kommer ifrån och bör undvikas i kursens programfiler.

Import kan köra kod

Satser på modulens toppnivå körs normalt första gången modulen importeras i en interpreterprocess. Funktionskroppar körs däremot först när funktionerna anropas. Python lagrar den importerade modulen i en cache, så samma modul laddas normalt bara en gång per session.

Döp inte din fil till random.py, json.py eller requests.py

Python söker tidigt i programmets egen katalog. En lokal fil med samma namn kan därför skugga den modul du avsåg att importera och ge förvirrande importfel.

03

Kod som följer med Python

Standardbiblioteket ger färdiga, dokumenterade verktyg

Standardbiblioteket innehåller moduler för bland annat slump, statistik, exakta bråk, filsystem och dataformat. De behöver inte installeras med pip, men måste importeras innan deras namn används.

random producerar pseudotillfälliga värden

Pseudotillfällig betyder att värdena skapas av en deterministisk algoritm som ser slumpmässig ut. Modulen passar spel och simuleringar men inte lösenord, tokens eller kryptografisk säkerhet; använd secrets för sådana ändamål.

choice(seq)
Returnerar ett slumpmässigt element ur en icke-tom sekvens.
randint(a, b)
Returnerar ett heltal i det slutna intervallet; både a och b kan väljas.
shuffle(lista)
Ändrar samma list på plats och returnerar None.
seed(värde)
Startar generatorn i ett känt tillstånd så att en följd kan reproduceras vid testning.
kort.pyPython
import random

kort = ["J", "Q", "K"]
random.shuffle(kort)

for kortnamn in kort:
    print(kortnamn)
Tilldela inte resultatet från shuffle

blandade = random.shuffle(kort) gör blandade till None. Funktionen ändrar redan listan kort. Om originalordningen ska bevaras måste du först skapa en kopia.

statistics

Sammanfatta numeriska data

statistik.pyPython
import statistics

varden = [10, 15, 20]
print("Medelvärde:", statistics.mean(varden))
print("Median:", statistics.median(varden))
ResultatMedelvärde: 15
Median: 15

mean beräknar aritmetiskt medelvärde. median ger mittvärdet när värdena ordnas.

fractions

Representera rationella tal exakt

brak.pyPython
from fractions import Fraction

summa = Fraction(3, 8) + Fraction(1, 6)
print(summa)
Resultat13/24

Fraction lagrar täljare och nämnare och förkortar resultatet. Det undviker vissa avrundningsproblem som binära float-värden har.

04

Data redan vid programstart

sys.argv är en list med kommandoradsargument

Ett kommandoradsargument skrivs efter filnamnet när programmet startas i terminalen. Modulen sys ger tillgång till listan argv, där varje element har typen str.

Index 0 är programmet

Kommandot python halsa.py Ada ger normalt två element: sys.argv[0] beskriver skriptet och sys.argv[1] är texten "Ada". Python omvandlar inte argument automatiskt; tal måste exempelvis skickas genom int eller float.

sys.argv[0]halsa.py · programfilen
sys.argv[1]Ada · första argumentet
len(sys.argv)2 · filnamnet räknas med
halsa.pyPython
import sys

if len(sys.argv) != 2:
    sys.exit("Användning: python halsa.py NAMN")

print(f"Hej, {sys.argv[1]}!")
ResultatHej, Ada!
sys.exit avslutar medvetet

Funktionen stoppar programmet innan ett osäkert index används. En text som argument skrivs som felmeddelande och ger en misslyckad exitstatus. Det är inte en krasch utan en kontrollerad validering av hur programmet startades.

Flera argument

Använd en slice

alla.pyPython
import sys

for namn in sys.argv[1:]:
    print(f"Hej, {namn}!")

[1:] skapar ett utsnitt från index 1 till slutet och utesluter programfilen.

Blanksteg i ett argument

Citera i terminalen

terminalPython
python halsa.py "Ada Lovelace"

Skalet delar normalt vid blanksteg. Citattecken gör Ada Lovelace till ett argument. Citattecknen blir normalt inte del av strängen.

Detta skrivs i terminalen, inte i Pythonfilen

python halsa.py Ada är ett kommando som startar programmet. Rader som börjar med import, if och print hör till filen.

05

Installera tredjepartskod

PyPI publicerar distributioner · pip installerar dem i en miljö

PyPI, Python Package Index, är ett register över Pythonprojekt. pip är ett installationsverktyg som hämtar och installerar distributioner och deras beroenden i en bestämd Pythonmiljö.

Installera där programmet ska köras

  1. Välj önskad conda-miljö som Pythoninterpreter i VS Code.
  2. Öppna en ny integrerad terminal och kontrollera att samma miljö är aktiv.
  3. Använd i första hand conda install paketnamn när paketet finns via dina conda-kanaler.
  4. När kursuppgiften anger PyPI använder du python -m pip install paketnamn i den aktiva miljön.
  5. Starta om Jupyter-kärnan efter en installation om importen fortfarande inte hittas.

python -m pip kör modulen pip med just den python som terminalen pekar på. Det minskar risken att installationen hamnar i en annan miljö.

VS Code-terminalPython
python -m pip install emoji
python -m pip install pyfiglet
python -m pip install inflect
python -m pip install requests
I en notebook

%pip använder aktuell kernel

Jupyter-kodcellPython
%pip install emoji

Procenttecknet markerar ett Jupyter-kommando. Starta om kärnan när installationen är klar om modulen inte kan importeras direkt.

Reproducerbarhet

Dokumentera beroenden

requirements.txtPython
emoji
pyfiglet
inflect
requests

En liten requirements.txt berättar vilka tredjepartsdistributioner projektet behöver. Installera med python -m pip install -r requirements.txt.

ModuleNotFoundError betyder inte alltid att package saknas överallt

Det kan vara installerat i en annan conda-miljö än den interpreter eller Jupyter-kernel som kör koden. Kontrollera också stavning och att ingen lokal fil skuggar importnamnet.

Tredjepartskod körs på din dator

Kontrollera projektets officiella dokumentation, underhåll, licens och exakta namn innan installation. Installera inte ett snarlikt namn på chans.

06

Program kommunicerar med program

Ett webb-API tar emot en request och skickar en response

Ett API, Application Programming Interface, är ett definierat gränssnitt mellan program. Ett webb-API använder ofta HTTP: programmet anropar en endpoint med parametrar och servern svarar med status, headers och en response body.

endpointserverns adress+paramsfrågans nyckel–värde-parHTTP requestrequests.getresponsestatus + body
itunes.pyPython
import requests

url = "https://itunes.apple.com/search"
params = {
    "entity": "song",
    "limit": 3,
    "term": "weezer",
}

response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
data = response.json()

Varje rad har ett kontrakt

params=
Låter requests koda query-parametrarna korrekt i URL:en.
timeout=10
Förhindrar att programmet väntar utan tidsgräns om servern inte svarar.
raise_for_status()
Skapar HTTPError för misslyckade HTTP-statuskoder.
response.json()
Avkodar JSON-body till motsvarande Pythonobjekt. Det bevisar inte i sig att HTTP-anropet lyckades.
saker_request.pyPython
try:
    response = requests.get(url, params=params, timeout=10)
    response.raise_for_status()
    data = response.json()
except requests.RequestException as error:
    print(f"Nätverksfel: {error}")
Nätverket är alltid en felkälla

DNS, anslutning, timeout, HTTP-status och serverns data kan misslyckas oberoende av din lokala kod. Alla undantag som requests uttryckligen skapar ärver från requests.RequestException, men ogiltig JSON kan också behöva hanteras separat.

JSON är text, inte ett dict

JSON, JavaScript Object Notation, är ett textformat för datautbyte. När JSON avkodas i Python blir ett JSON-object normalt ett dict och en JSON-array en list. true, false och null blir True, False och None.

json.dumps(data, indent=2, ensure_ascii=False) gör den motsatta riktningen för visning: den kodar ett Pythonobjekt till en formaterad JSON-str. Den ändrar inte ursprungsobjektet.

las_resultat.pyPython
import json

print(json.dumps(data, indent=2, ensure_ascii=False))

for result in data["results"]:
    print(result["artistName"], result["trackName"])
API-nycklar är hemligheter

En API-nyckel identifierar och ofta kvoterar din åtkomst. Skriv inte in den i kod som commitas till GitHub. Använd en miljövariabel eller en lokal konfigurationsfil som uttryckligen ignoreras av Git, och följ tjänstens aktuella instruktioner.

07

Återanvänd din egen kod

En egen .py-fil kan importeras som modul

Flytta funktioner som har ett tydligt ansvar till en separat fil. Håll demonstration, frågor till användaren och andra sidoeffekter bakom en main-funktion så att en import bara gör funktionerna tillgängliga.

Modulen

sayings.py

sayings.pyPython
def hello(name):
    print(f"Hej, {name}!")

def goodbye(name):
    print(f"Hej då, {name}!")

Filen definierar två funktioner men frågar inte användaren och skriver inget vid import.

Programmet

app.py

app.pyPython
from sayings import hello

hello("Ada")
ResultatHej, Ada!

När filerna ligger i samma projektmapp kan app.py importera och anropa funktionen.

sayings.pyPython
def main():
    name = input("Namn: ")
    hello(name)

if __name__ == "__main__":
    main()

__name__ visar hur filen används

När sayings.py körs direkt sätter Python modulens globala variabel __name__ till strängen "__main__". Då är villkoret sant och main() körs.

När filen importeras får __name__ i stället modulnamnet "sayings". Villkoret blir falskt, så den interaktiva demonstrationskoden körs inte. Funktionerna ovanför finns ändå tillgängliga.

Guard, inte magi

Raden if __name__ == "__main__": är en vanlig if-sats som jämför två strängar. Den skyddar kod som bara ska köras när filen är programmets startpunkt.

Undvik cirkulära importer

Om a.py importerar b.py samtidigt som b.py importerar a.py kan modulerna vara ofullständigt initialiserade när namn används. Flytta gemensam kod till en tredje modul eller ompröva ansvarsfördelningen.

Problem Set 4

Sex övningar i Pythons ekosystem

Harvards aktuella uppgiftssidor är kravspecifikationen. Äldre lokala exempel kan använda föråldrade API-adresser eller missa detaljer.

01

Emojize

Installera distributionen emoji, läs en engelsk str och omvandla emoji-koder och aliases till faktiska emoji. Läs dokumentationen för det namngivna argumentet language.

Testa: :1st_place_medal:, :money_bag:, :smile_cat: och vanlig text.

Aktuell uppgift ↗
02

Frank, Ian and Glen's Letters

Använd pyfiglet. Programmet accepterar antingen inga argument efter filnamnet eller exakt -f FONT/--font FONT. Annan användning ska avslutas med sys.exit.

Testa: inga argument, giltiga fonter, fel flagga, okänd font och fel antal argument.

Aktuell uppgift ↗
03

Adieu, Adieu

Samla minst ett namn till EOFError och använd inflect för att sammanfoga namnen med korrekt and och Oxfordkomma.

Testa: ett, två, tre och fem namn före EOF.

Aktuell uppgift ↗
04

Guessing Game

Läs en positiv nivå, generera ett heltal mellan 1 och nivån inklusive och fråga efter positiva gissningar tills svaret är rätt. Ange Too small!, Too large! eller Just right!.

Testa: text och negativa värden för både nivå och gissning, nivån 1 samt gissningar utanför intervallet.

Aktuell uppgift ↗
05

Little Professor

Godkänn nivå 1, 2 eller 3. Skapa tio additionsproblem med rätt antal siffror. Varje problem ger tre försök; fel svar eller icke-tal skriver EEE. Skriv korrekt svar efter tre fel och avsluta med poäng 0–10.

Observera: nivå 1 använder 0–9; nivå 2 använder 10–99; nivå 3 använder 100–999. generate_integer ska skapa ValueError för annan nivå.

Aktuell uppgift ↗
06

Bitcoin Price Index

Läs antalet bitcoin som kommandoradsargument och omvandla till float. Anropa aktuella CoinCap v3, hantera requests.RequestException, läs data → priceUsd, omvandla priset och skriv kostnaden med tusentalsavgränsare och fyra decimaler.

Viktigt: uppgiften kräver numera ett CoinCap-konto och en API-nyckel. Lägg aldrig nyckeln i ett GitHub-repository.

Aktuell uppgift ↗
Två lokala exempel är särskilt föråldrade

Den äldre Bitcoinfilen använder CoinDesk-adressen, men den aktuella uppgiften använder CoinCap v3 och API-nyckel. Äldre Little Professor-kod kan också generera fel intervall för nivå 2 och 3. Följ alltid de aktuella Harvardkraven.

Fortsätt arbeta

Resurser och självkontroll

Använd notebooken för experiment, den här sidan för begreppen och originaldokumentationen för varje modul och package.

Efter lektionen kan jag …

skilja modul, package, distribution och informella ordet library

välja mellan import modul och from modul import namn

använda random utan att blanda ihop mutation och returvärde

validera sys.argv innan ett index används

installera i samma miljö som kör programmet

förklara endpoint, parametrar, response, status och JSON

skapa en egen modul med en korrekt __name__-guard