Python del 5 - Skapa program

Den här delen var på väg att bli en del om klasser, men jag kom på att det nog var bättre om jag gick igenom hur man gör program, hur man gör moduler, få hjälp med att läsa dokumentationen och lite annat smått och gott. Min förhoppning är att ni med den här delen ska kunna skriva vad som helst, även om klasser kommer att hjälpa till att göra programmen mer strukturerade.

Vad skiljer ett program från det ni har skrivit hittills? Ingenting faktiskt. Ta all kod ni vill ha och spara det i en textfil så har ni ett program! Lite mer tänkte jag dock säga innan jag anser att den här delen är klar.

Varje pythonprogram bör börja med raden

  1. #!/usr/bin/env python
  2.  

Så varför ska man skriva den där rotvälskan? Den raden är främst till för linuxanvändare, men om ni som kör windows lägger till den här raden underlättar ni för de som använder linux, och eftersom det i övrigt är samma kod så kan ni väl lägga till den? Det är inte så svårt... Raden betyder att det är programmet python som ska tolka koden. Det betyder att man (i *nix) kan skriva
$ ./programnamn
istället för
$ python programnamn


Skriver du på vanlig svenska med svenska tecken bör du också ta med följande rad i alla sina program
  1. # -*- coding: ISO-8859-1 -*-
  2.  

Den gör att du får å, ä och ö på rätt sätt. Antagligen ser det rätt ut ändå, men du kommer få massor varningar.
Notera att du Måste skriva den första av de två raderna på den Första raden om den ska fungera. Inga radbrytningar eller något annat innan. Den andra raden av de jag skrev bör stå innan din kod börjar skriva.

Nu har vi fått till början av programmet. Nu ska jag berätta om moduler. Moduler är samma sak som det som C/C++ kallar för includefiles. En modul är helt enkelt en samling av användbara funktioner och klasser för att göra en specifik syssla. Modulen string innehåller t ex stränghanteringsfunktioner. Jag tänkte att vi kan titta lite närmare på modulen random, som innehåller funktioner för att slumpa fram tal. Vi ska börja med att gå igenom rad för rad vad vi gör, och när vi är klara så ska vi komma att ha ett helt program som ska skriva ut slumptal. Jag kommer att skriva för live-tolken när jag skriver och testar, och jag rekomenderar att ni också testar koden (både min och er) i live-tolken först, och när den funkar så kan ni klistra in den i programet. Men det är bara min åsikt.
Javisst ja! Jag höll på att glömma att berätta för er om funktionen dir(). Skriver ni dir() i live-tolken (eller i ett program) så kommer alla programmets objekt att skrivas ut. Skriver ni dir(funktion) t ex så kommer ni att få se allt som finns i funktionen. Vi ska använde dir() på bl a moduler.

Ok, dags att dra igång. Först ska vi titta på funktionen och sen ska vi importera modulen
  1. >>> dir()
  2. ['__builtins__', '__doc__', '__name__']
  3. >>> import random
  4. >>> dir()
  5. ['__builtins__', '__doc__', '__name__', 'random']

Nu ligger alltså modulen importerad. Ska vi ta och titta på den också?
  1. >>> dir(random)
  2. ['BPF', 'LOG4', 'NV_MAGICCONST', 'Random', 'SG_MAGICCONST', 'TWOPI', 'WichmannHill', '_BuiltinMethodType', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '_acos', '_cos', '_e', '_exp', '_floor', '_inst', '_log', '_pi', '_random', '_sin', '_sqrt', '_test', '_test_generator', 'betavariate', 'choice', 'cunifvariate', 'expovariate', 'gammavariate', 'gauss', 'getstate', 'jumpahead', 'lognormvariate', 'normalvariate', 'paretovariate', 'randint', 'random', 'randrange', 'sample', 'seed', 'setstate', 'shuffle', 'stdgamma', 'uniform', 'vonmisesvariate', 'weibullvariate']

Det där behövs förklaras... Sakerna som har __ (två underscores) runt omkring själva namnet har oftast speciella betydelser. De med _ (ett underscore) innan namnet är pythons motsvarighet till privata klassmedlemmar (kommer mer om det i nästa del). Det som är viktigt med dem är att Inte röra, såvida du inte vet att du vet vad du gör! Men allt annat då..? Jag föreslår att vi tittar på pythons dokumentation. Windowsanvändare får med en dokumentation (Help->Python Docs i IDLE), och vi andra får ta och titta på Webben (http://python.org/doc). Vi letar reda på avdelningen module index och sen random (http://docs.python.org/lib/module-random.html). Nu ska vi se vad det står... "Generejt psevdo random..." Det låter utmärkt för vad vi ska göra!

Om vi vill kan vi också skriva ut modulens egen dokumetation
  1. >>> print random.__doc__
Det skulle bli så mycket att klistra in här vad det kommer upp, så ni får kolla själva.

Var var vi nu? Visst ja! Vi tittar på hjälp-filen. Den första funktionen, seed, behövs så att slumpgeneratorn kan börja slumpa tal. Sen vill vi ha ett tal vid en specifik tidpunkt. Vad ska vi ha då..? Hm... Vi vill ha en funktion för integers... Vad sägs om... randint? Den tar vi, sa polisen.
  1. >>> seed()
  2. Traceback (most recent call last):
  3. File "pyshell", line 1, in -toplevel-
  4. seed()
  5. NameError: name 'seed' is not defined

Men vaf..? Varför funkar inte det? Vi har ju importerat random. Hm... Javisst ja! Funktionen seed() tillhör ju random, alltså måste vi ju anropa funktionen som ligger inne i random.
  1. >>> random.seed()
  2. >>> random.randint(1, 10)
  3. 5

Det behöver inte vara en femma du får. Givetvis inte, då hade det inte varit mycket till slumpfunktion. Ska vi skapa ett program? Jag lägger till lite grejer som ni bör känna till, och så skriver jag följande program.
  1. #!/usr/bin/env python
  2. # -*- coding: ISO-8859-1 -*-
  3.  
  4. import random
  5.  
  6. print "Nu ska vi skapa slumptal!"
  7. minst = int(raw_input("Skriv undre gränsen: ")) #int() förvandlar den strängen som raw_input() ger till en integer, ett tal
  8. mest = int(raw_input("Skriv övre gränsen: "))
  9. print "Here we go! Tjugo tal kommer skrivas ut"
  10. random.seed()
  11. i = 0
  12. while(i<20):
  13. print random.randint(minst, mest)
  14. i+=1
  15. print "Sådär! Nu avslutar vi. Ciao!"

Vårt första hela program! Det var väl inte så svårt? Ganska meningslöst, men ändå! Men hur kör man det då..?
I Windows räcker det förhoppningsvis att klicka på det, eller möjligen måste man välja att man vill köra det med python. I Linux kan man antingen bara köra filen med python (python filnamn.py) eller så kan man göra filen körbar (chmod +x filnamn.py) och sen exekvera den (./filnamn.py). Ett sätt som jag anser vara väldigt smidigt och som funkar i alla möjliga operativsystem är att öppna/skapa filen i IDLE och välja "Run module". Då kommer den att köras i ett annat fönster, och om programmet eventuellt skulle krasha så kan du fortsätta i live-tolk-läge där ditt program dog. Med hjälp av bl a dir() kan du då undersöka vad som finns och vad som inte finns. Detta ger dig ett väldigt kraftfullt verktyg för att debugga.

Nu tillbaka till att importera filer. För att importera en av dina egna filer skriver du likadant som förut fast byter ut modulnamnet mot filnamnet, fast utan ändelsen. Om vi låtsas att du har filen "mitt_progg.py" så skriver du
  1. import mitt_progg
och så blir det som står i den filen importerat i ditt program. Notera att filen du importerar bör ligga i samma mapp som filen som inkluderas.

Och förresten: tro inte att imports bara går att göra i program. Allt som du kan göra i program går att göra i livetolken och vise versa.

Det finns ett annat sätt att importera moduler och filer. Det är lite buggigt, så det är inte rekomenderat om du ska hålla på att modifiera filen du importerar t ex (det lärde jag mig den hårda vägen), men det fungerar bra till vanlig enkel användning. Det ser ut såhär:
  1. from modulnamn import funktion
Såhär kan vi slimma ner programmet lite om vi bara ska ha ett enda objekt. Men har vi otur kan ju det objektet ha beroenden i den modulen, så det kan bli knepigt. Det lite finurliga är att du kan skriva * som funktion och på så sätt inkludera hela modulen, men slippa skriva t ex random.funktion varje gång du ska använda den. Det räcker med funktion. Ett litet bevis
  1. >>> dir() #Kollar hur det ser ut från början
  2. ['__builtins__', '__doc__', '__name__']
  3. >>> from random import seed #importerar bara en funktion
  4. >>> dir() #...och den ligger där den ska
  5. ['__builtins__', '__doc__', '__name__', 'seed']
  6. >>> from random import * #importerar allt i random
  7. >>> dir()
  8. ['Random', 'WichmannHill', '__builtins__', '__doc__', '__name__', 'betavariate', 'choice', 'cunifvariate', 'expovariate', 'gammavariate', 'gauss', 'getstate', 'jumpahead', 'lognormvariate', 'normalvariate', 'paretovariate', 'randint', 'random', 'randrange', 'sample', 'seed', 'setstate', 'shuffle', 'stdgamma', 'uniform', 'vonmisesvariate', 'weibullvariate']

Jag tycker att det sista som tolken spottade ur sig är ganska så väldigt likt det som tolken spottade ur sig när vi skrev dir(random) förut.

Hur ser då de här modulerna som vi inkluderar ut? Det är helt vanlig kod som ligger i vissa förutbestämda mappar. Först och främst letar tolken efter filen i den aktuella mappen, så dina egna filer har högst prioritet. Sen undersöker den variabeln PYTHONPATH. Den innehåller en lista med mappar som skapas vid uppstart. Den kan användaren modifiera genom att lägga till fler sökvägar till sina egna moduler. Till slut undersöker tolken om modulen finns i standardsökvägen, som avgörs när python installeras. I min windowsinstallation är detta C:Python23Lib. I GNU/Linux är det vanligen /usr/local/lib/python. Om ni kollar i den mappen kan ni t ex hitta random som vi nyss pysslade med.

Ni ser antagligen också filer med ändelsen .pyc. Vad är det? Det är sk kompilerade pythonfiler. Kompilerade pythonfiler skapas när man använder en fil skulle man kunna säga. Det görs (helt automatiskt) så att du ska kunna köra filerna lite snabbare nästa gång du använder dem.

Ytterligare en sak som ni nog ser är ett gäng mappar. En sådan mapp är (antagligen) ett paket. Med ett paket kan man samla många funktioner i många filer (förslagsvis inom samma område) på ett ställe. I alla mapparna finns det en fil som heter __init__.py. Den filen är viktig, eftersom det är den som skiljer ett paket från en mapp med filer. Den behöver inte innehålla något, men den måste finnas. Vill du inkludera t ex filen kaka.py i modulen mat så skriver du
  1. include mat.kaka


I Linux har vi ju redan kommit fram till hur man skapar en exekverbar fil (chmod). Dock kräver det att användaren har python installerat. Det finns en modul (som jag aldrig har använt, men eventuellt ska jag titta lite på den här senare) som heter py2exe som används för att skapa en exefil (bara windows alltså) som går att använda utan förinstallera tolken. Går att hitta här: http://starship.python.net/crew/theller/py2exe/

Källa: http://blinkenlights.se/