tisdag 11 december 2012

Övningar med listor

Alla positiva heltal som inte själva är primtal går att dela upp i produkter av primtal. Detta kallas primtalsuppdelning. Ex: 28 = 2*2*7, 72 = 2*2*2*3*3, 39 = 3*13

Detta kan bland annat användas för att göra listor på primtal och för att göra snabbare funktion för att finna största gemensamma delare.

Övning 2.13
Lägg till en funktion till modulen diskret_matematik för  att skapa en funktion som utför primtalsuppdelning enligt nedanstående pseudokod:

def primtalsuppdelning(n):
    Skapa en tom lista kallad primtal
    sätt variabeln p till 2
    så länge som p är mindre eller lika med n:
        om n är jämnt delbart med p:
            lägg till p i listan primtal
            dividera n med p
        annars :
            öka p med ett
            
    returnera primtal

Övning 2.14
Använd primtalsuppdelningen ovan till att göra en betydligt effektivare version av funktionen sgd(a, b). Byt ut den befintliga mot denna version. Pseudokod:

def sgd(a, b):
    sätt storst till det största talet av a och b samt
    minst till det minsta
        
    om storst jämnt delbart med minst returnera minst
    primtalsuppdela minst och spara resultatet i listan prim
    antag att största gemensamma delare, sgd är 1
    för alla tal p i prim :
        om storst jämnt delbart med p :
            dela storst med p
            multiplicera sgd med p
            
    returnera sgd


Övning 2.15
Uppdatera main() i diskret_matematik med tester av primtalsuppdelningen och testkör.

Uppgift 2.5
Skriv ett program som hittar primtal genom att använda Eratosthenes såll.
Bild: Wikipedia

onsdag 5 december 2012

Mer om listor

Forsatsen och listor

Om du inte behöver veta indexet kan du använda dig av for-satsens förmåga att iterera över listor.

Övning 2.9

lista = ["Hej", "alla", "glada"]

for e in lista :
    print(e, end = " ")

 Listor är objekt

Listor är objekt i Python. Det skiljer dem från tal och strängar. Objekt är behållare för variabler och även i många fall metoder. Deras innehåll kan förändras utan att skapa ett nytt objekt.

Jämför hur du lade ihop två textsträngar med:

s = s + t

du inte kan förändra strängen s utan måste skapa en ny sträng som sedan ersätter den gamla i s. Med hur du lägger till en lista till en annan lista:

li.extend(li2)

I detta fall läggs elementen i li2 till de i listan li direkt. Detta då li är ett objekt som  innehåller ett antal element.

Namnen på objekt kallas identifierare då de namnger ett unikt objekt.

Till skillnad mot strängar är listor alltså ändringsbara efter det de skapats. Du kan ändra de ingående elementen i listan.

Övning 2.10
Skriv och testa nedanstående program

lista = [1, 2, 3, 4]
lista[0] = 5
lista[1] = lista[3]
lista[3] lista[3]/2
print(lista)

OBS! Objekt överförs via referens
Den viktigaste skillnaden mellan variabler och objekt är att variabler överförs via värdet och objekt via referens.

Övning 2.11
Skriv in nedanstående program och testa. Notera resultatet. Vad händer här?

s = "Hej"
t = s
t = t + " på dej."
print("Variabler")
print ("s="+s)
print ("t="+t)

li = ["Hej"]
li2 = li
li2.extend(["på","dej"])
print("Objekt")
print ("li="+str(li))
print ("li2="+str(li2))

För strängarna så har s kvar sitt värde ("Hej") när t förändrats. För listobjekten förändras även li när li2 ändras. Det beror på att li2 = li gör att båda identifierarna refererar till samma objekt. Se figuren nedan:


Ovanstående skillnad är speciellt viktigt när du använder objekt som argument i funktioner. Du kan skriva funktioner som gör förändringar i det objekt som ges som funktionsargument. Ex:

Övning 2.12
Följande funktion byter ut element i en lista. Element som är lika med bort byts ut mot element som anges i till

def bytut(li, bort, till):
    #Byter ut elementet i bort mot det i till i listan li
    for i in range(len(li)) :
        if li[i] == bort :
            li[i]=till

lista = [1, 2, 3, 4, 2]          
bytut(lista, 2, 8)
print(lista)

Notera att ingen return-sats behövs i funktionen då den arbetar via referens med listan som ges i argumentet.

Kopior av listor
Ibland vill du ha en kopia av en lista som du kan arbeta med. Alltså skapa ett nytt listobjekt med samma innehåll som det ursprungliga. Då kan du använda en for-sats och iterera över ursprungliga listans element. Följande skapar en ny lista li2 och fyller den med elementen i li:

li2 = []
for e in li : li2.append(e)

Listor och strängar
Listor kan även innehålla strängar och strängar kan omvandlas till listor av tecken.

För att omvandla en sträng till en teckenlista används li = list(s) där s är den sträng som skall delas upp.

För att omvandla en lista med tecken eller strängar till en sträng används s.join(li) där s är ursprungssträgen och li innehåller de tecken som ska läggas till. Följande ger text="abc":

li = ["a", "b", "c"]
text = "".join(li)

Uppgift 2.4
Skriv din egen vändnings-funktion som byter ordningen för elementen i en lista av tal eller strängar. Se nedanstående pseudokod.

def reversera(lista):
    medan index, i, mindre än halva listlängden
        spara temporärt värdet för elementet i från slutet
        sätt värdet på elementet i från slutet till det för i från början
        sätt värdet på elementet i från början till det sparade värdet
        öka i med ett

onsdag 28 november 2012

Introduktion till listor

Om du behöver två tal för en beräkning kan du skapa två variabler, en för varje tal. Men hur gör du om du behöver 100 tal. Än värre om du inte vet i förväg exakt hur många tal som du vill använda?

Listor löser det problemet. En lista är ett objekt som kan innehålla många tal, strängar (texter) mm. till och med andra listor.

Listor och index

Ett sätt att se på listor är som en rad med lådor. Hela raden tillsammans bildar listan och varje låda kan fyllas med olika innehåll. För att kunna hitta rätt låda är de numrerade, indexerade, från 0 och uppåt. Varje låda kallas ett element i listan.  Bilden nedan visar hur man i Python skapar listan min_lista och samtidigt fyller den med 6 olika tal samt hur man kan tänka sig talen placerade i lådor efter varandra numrerade 0 till 5.  Notera att indexeringen börjar på 0!


För att läsa av ett element i listan anger man listans namn följt av indexet för elementet inom hakparenteser. Tex. print(min_lista[2]) skriver ut talet 30.

Vill man ha reda på hur många element som finns i listan kan man använda funktionen len(<listans namn>).  Tex. ger len(min_lista) svaret 6

Övning 2.5
Skriv följande program som skapar ovanstående lista samt skriver ut de ingående elementen.

min_lista=[70, 40, 30, 40, 20, 80]
for i in range(len(min_lista)) :
    print(min_lista[i])

Man kan notera att range(len(min_lista)) faktiskt skapar en ny (namnlös) lista [0, 1, 2, 3, 4, 5] som sedan används för att gå igenom indexen i min_lista.

Övning 2.6
Det går utmärkt att skriva ut en lista med print. Då skrivs den ut med hakparenteser och kommatecken. Byt ut for-loopen i övning 2.5 mot print(min_lista) och testa.


Praktiska list-metoder

Förutom len-funktionen så finns det flera metoder som är unika just för listor som hjälper programmeraren. Dessa skrivs som listans namn, punkt, metoden. Till exempel min_lista.append(90) som lägger till ett nytt element sist i listan med värdet 90. 

Tabellen nedan visar standardfunktionerna:
Metod Beskrivning
append(x) Lägger till ett nytt element sist i listan och fyller det med x
count(x) Räknar hur många element i listan som är lika med x
extend(li) Sätter i hop två listor till en. Listan li läggs till efter den ursprungliga listan.
index(x) Letar upp det första elementet som är lika med x och returnerar indexet för detta element.
insert(i, x) Stoppar in x som ett nytt element på platsen i. Det element som förut hade index i flyttas upp till i+1 och hela listans längd ökar med 1.
pop() Returnerar det sista elementet i listan och tar bort det. Listans längd minskar med 1
remove(x) Raderar det första elementet som är lika med x. Listans längd krymper med 1.
reverse() Vänder ordningen på elementen i listan.
sort() Sorterar listan i storleksordning från minsta till största elementet


Radera element
Som synes ovan saknas en viktig metod. Nämligen att kunna ta bort ett eller flera element mitt i lista om man vet indexet. Detta görs istället med kommandot del:

 del li[i:j]

Ovanstående tar bort alla element från och med index i till (inte till och med!) j ur listan li och krymper den med motsvarande längd.

Notera: Kommandot del kan även användas för att radera variabler, hela listor och mycket annat

Fylla en lista med ett värde
Det är vanligt att man vill fylla en lista med ett och samma initialvärde, ofta noll. Detta kan i Python göras med *-tecken som för strängar. Följande fyller listan li med n st nollor:

li = [0] * n

Övning 2.7
Skriv och kör följande program som testar de olika metoderna samt kommandot del.

min_lista=[70, 40, 30, 40, 20, 80]
print(min_lista)

print("append 90")
min_lista.append(90)
print(min_lista)

print("count för 40")
print(min_lista.count(40))

print("extend med listan [60, 50, 90]")
li=[60, 50, 90]
min_lista.extend(li)
print(min_lista)

print("index för 90")
print(min_lista.index(90))

print("insert 10 på index 1")
min_lista.insert(1,10)
print(min_lista)

print("pop")
print(min_lista.pop())
print(min_lista)

print("remove 60")
min_lista.remove(60)
print(min_lista)

print("reverse")
min_lista.reverse()
print(min_lista)

print("sort")
min_lista.sort()
print(min_lista)

print("Raderar från och med index 3 till index 6")
del min_lista[3:6]
print(min_lista)

Övning 2.8
Skriv och testa följande program som fyller på en lista med tal som användaren matar in.

a=[] #Skapar en tom lista

#Fyller på listan
while True :
    try :
        s=input("Ange ett tal (N för att sluta):")
        e = float(s)
        a.append(e)
    except ValueError :
        if s == "N" : break
        else : print("Fel. Försök igen")

print(a)

Uppgift 2.3
Använd övning 2.8 samt listmetoder för att skriva ett program som talar om medianen av de inskrivna talen.

onsdag 21 november 2012

Moduler


Moduler

För att kunna återanvända funktioner  i olika program kan man samla dem i filer. I Python heter filer med funktionssamlingar moduler. (Även filer med hela program kallas moduler). Vi har tidigare använt modulen math som innehåller många matematiska funktioner samt modulen random som har slumptalsfunktioner.

Modulens namn är samma som filnamnet men utan filnamnstillägget (.py).

När du importerar en modul importeras funktionerna till programmet och kan användas genom  minmodul.minfunktion(). Ex:

#importerar modulen
import minmodul

#Kör en funktion i den importerade modulen
minmodul.minfunktion()

OBS! Om du importerar en modul kommer eventuell programkod utanför funktioner att köras direkt. Se nedan.

Övning 2.4 2.4b
Du ska nu skapa en modul med funktioner för matematik kring division och primtal. Använd nedanstående pseudokod för att skapa funktionerna. Namnge modulen som diskret_matematik

Funktionen primtal(n)
Kontrollerar om ett heltal tal n är ett primtal:

def primtal(n) :
    beräkna roten ur n (högsta möjliga talet som kan vara ett primtal)
    Sätt variabeln primtal till sant

    för alla heltal från och med 2 till och med roten ur n:
        om n är jämnt delbart med talet:
            sätt primtal lika med falskt
            hoppa ur loopen
        
    returnera värdet på primtal

Funktionen sgd(a, b)
Hittar största gemensamma delare hos för två heltal tal a och b:

def sgd(a, b) :
    om a större än b sätt variabeln storst till a och minst till b 
    annars sätt minst till a och storst till b
    
    om storst och minst är delbara returnera minst
    
    bestäm roten ur minsta talet plus 1
    
    för alla tal i från hetalsdelen av minst/2 till och med 1 :
        om både storst och minst går att dela med i :
            hoppa ur loopen
        
    returnera i

Funktionen mgn(a, b)
Hittar minsta gemensamma nämnare för två nämnare a och b:

    
def mgn(a, b) :
    returnera a multiplicerat med b delat med resultatet av sgd(a, b)


Funktionen main()

Ibland vill man ha programkod i en modul som ska importeras i andra program. För att förhindra att koden körs vid import används följande kod:

def minfunktion1()
    ...

def minfunktion2()
    ....

....

def main()
    # Kod som ska köras när modulen körs utan import

if __name__ == "__main__":
    main()

Variablen __name__ är en inbyggd variabel i Python som innehåller namnet på modulen om den importerats av ett program men "__main__" om modulen körs direkt.

Koden gör alltså att det du skrivit i funktionen main() endast körs om koden inte importeras.

Notera att namnet main() inte är något speciellt. Du kan skriva vilket funktionsnamn du önskar men main() har blivit en de facto standard.

Inlämningsuppgift 2.2
Lägg till en main()-funktion med tillhörande if-sats. Skriv kod som testar modulens funktioner.

måndag 19 november 2012

Speciella tal

Nedan följer några speciella tal som kan vara bra att känna till

Största heltalet
Det största heltalet som kan användas som index i till exempel strängar kan du finna med satsen sys.maxsize:

import sys

print(sys.maxsize)

Största flyttalet
Största decimaltalet som datorn klarar av ges av sys.float_info.max

import sys

print(sys.float_info.max)

Oändligheten och Not a Number
Inom matematiken finns det ibland  behov av att använda plus eller minus oändligheten. De skrivs:

float("Infinity")
float("-Infinity")

Funktionen math.isinf(x) returnerar sant om talet x är antingen positiva eller negativa oändligheten. (Du måste importera math-modulen för denna funktion.)
 
Ett annat speciellt "tal" är NaN, Not a Number, som är användbart när funktioner skall returnera ett flyttalsvärde men ett sådant inte går att räkna ut. Exempelvis grund av negativt tal under roten eller division med noll.

import math
x = float(input("Skriv ett tal"))
if x <o :
    x = float("nan")
else :
    x = math.sqrt(x)
print(x)

Det går att prova om talet är NaN med funktionen math.isnan(x) som returnerar sant om x är ett NaN.


Övning 2.4
Skriv om inlämningsuppgift 1.2 så att kontrollen av om det finns rötter och själva rotberäkningen sker i en funktion som returnerar NaN om talet under roten är negativt annars den beräknade roten. Se nedanstående pseudokod:

def roten(p, q) :
    t = talet under roten
    om t är negativt
        return NAN
    annars
        retur roten ur t

input p och q
r = roten(p,q)
om r NaN svara med att den saknar rötter
annars beräkna de två rötterna

Inlämningsuppgift 2.1
Skriv ett program som låter användaren mata in ett valfritt antal tal. Inmatningen avslutas med att användaren skriver ”N”. När alla talen är inmatade skriver programmet ut det största och det minsta av talen.

onsdag 14 november 2012

Funktioner

Del 2

Funktioner

Funktioner i programmering är en generalisering av funktionsbegreppet från matematiken. Se nedanstående bild där en matematisk definition av f(x) jämförs med motsvarande i Python:
Funktionerna har namnet f, de beror på variabeln x som kallas funktionens argument, och uttrycket definierar funktionen.

För Python gäller
  • Nyckelordet def inleder en funktionsdefinition
  • funktionens namn följs av en parentes med en kommaseparerad lista på argument. En funktion kan ha inga eller flera argument. Satsen avslutas med :
  • Ett block satser utgör koden i funktionen.
  • Satsen return följs av det värde eller objekt som skall returneras av funktionen. Satsen return är ej nödvändig. Om den saknas returnerar funktionen inget.
  • Funktionen avslutas när den når en return-sats eller när sista satsen i det indragna blocket exekverats.

Exempel på funktioner

Bilden ovan visar hur en funktion du känner igen från matematiken definieras i Python. Här följer några andra varianter av funktioner.

Största talet
Returnerar det tal som är störst av två tal a och b.

def storst(a, b) :
    if a > b : return a
    else : return b

Denna funktion har två argument och returnerar ett tal..

Slumpar en tipsrad
Returnerar en sträng "1", "X" eller "2". Obs! funktionen kräver en sats import random i början av filen för att fungera.

def tipsrad() :
    t = random.randint(1,3)
    if t == 1 : return "1  "
    elif t == 2 : return " X "
    else : return "  2"

Denna funktion har inget argument men returnerar en sträng.

Instruktionstext
Skriver ut instruktion till användaren.

def instruktion() :
    print("Välkommen till Månlanda!")
    print("Ditt mål är att landa mjukt.")
    print("Du har begränsad mängd bränsle. Lycka till!")

Denna funktion har varken argument eller returnerar ett värde. Dock är dessa typer av funktioner användbara för att förpacka kod. Antingen för att den ska upprepas på olika ställen i programmet eller för att göra programmet tydligare att läsa.

Rövarspråket
Gör om en text till rövarspråket.

def rovarsprak(text) :
   rt=""
   for c in text.lower() :
       if c in "bcdfghjklmnpqrstvwxz" :
           rt=rt+c+"o"+c
       else :
           rt=rt+c
 return rt

Denna funktion har en sträng som argument och returnerar en annan sträng som byggs upp från argumentet. Funktionen initierar en variabel, rt,  inom funktionen. Se mer om detta nedan.

Att använda funktioner

Före en funktion kan användas måste den vara definierad. Om funktionen i sin tur använder importerade funktioner måste importeringen göras före funktionsdefinitionen. Alltså placeras definitionerna före den kod som refererar till funktionen och efter eventuella importer. En god programstruktur är denna:
  1. importer
  2. globala variabler och konstanter (se nedan)
  3. funktionsdefinitioner
  4. huvudprogrammet
För att anropa en funktion  används funktionens namn följt av de argument man behöver skicka med.

Exempel på program som använder tipsradsfunktionen:

import random

def tipsrad() :
    t = random.randint(1,3)
    if t == 1 : return "1  "
    elif t == 2 : return " X "
    else : return "  2"

print("Tipsrad")
for i in range(13) :
    print(tipsrad())
print("====")

Övning 2.1
Skriv ett program som testar alla funktioner i ovanstående exempel.

Uppgift 2.1
Skriv en funktion som omvandlar temperatur i Fahrenheit till Celsius.

Variablers synlighet och överföring av argument

Variabler har olika synlighet (eng. scope). Det vill säga om de är nåbara från olika delar i programmet. I Python fungerar synligheten för variabler ungefär som tonade rutor i en bil. Variabler i huvudprogrammet är synliga inne i funktionen medan variabler i funktionen inte syns utanför.
  • Variabeln a kallas en global variabel och nås även inne i funktionen för avläsning av värdet ej ändring.
  • Funktionens namn f är synlig både i funktionen och utanför.
  • Argumentet x är en lokal variabel i funktionen och nås inte utifrån
  • Variabeln b initieras i funktionen och är endast nåbar inom funktionen
Om en variabel i en funktion har samma namn som en global så används den lokala variabeln.

Funktionsvariabler och argument raderas ur minnet när funktionen är avslutad. De globala variablerna "lever" under hela programkörningen.

De allra flesta språk har synlighetsregler liknande Python även om skillnader kan förekomma.

Variabler överförs till funktionsargument genom sitt värde. Alltså x i funktionen ovan får värdet 5 om den hade anropats med f(a). Eller med andra ord: när funktionen anropas skapas variabeln x och tilldelas värdet som lagras i a.

Notera: Objekt överförs via referens vilket gör att de hanteras annorlunda. Vi ser på det senare i kursen.

Övning 2.2
Skriv nedanstående program och testa.

a = 5
b = 2

def f(x) :
    a = x
    print("I funktionen a=" + str(a) + " x=" + str(x))

f(b)
print("Utanför funktionen a=" + str(a))

Notera:
Den globala variabeln a behåller sitt värde efter att funktionen returnerat.
Variabeln x får samma värde som b.

Övning 2.3

Varför fungerar inte nedanstående program?

a = 5

def f(x) :
    b = x + a
    print(b)

f(3)
print(b)


Undvik att använda globala variabler i funktioner
Det är lockande att använda globala variabler i funktioner men det bör undvikas om du inte har mycket goda skäl. Poängen med funktioner är att de ska vara återanvändningsbara i olika sammanhang. Om en funktion är beroende av variabler definierade utanför funktionen försvinner den möjligheten. Funktionen i uppgift 11 skulle ha skrivits och anropats enligt nedanstående exempel i ett riktigt program:

a=5
 
def f(x, y) :
    b = x + y
    print(b)

f(3,a) 


Uppgift 2.2
Skriv om programmet i repetitionsuppgift 1.8 så att själva testet om det är ett primtal görs i en funktion som returnerar sant eller falskt.

Överkurs
Python har en variant av anonym funktion (funktion utan namn) som kallas lambda.
Den återfinns även i språket Lisp. Du kan läsa om lambda här.

tisdag 6 november 2012

Mer repetitionsövningar på del 1

Rep 12
Slutför programmet så att du får en utskrift av "Hej på dej" utan att ändra i de givna raderna.

h = "Hej"
p = "på dej" 


Rep 13
Skriv ett program som finner det första stället då strängen "hus" förekommer i texten "Vissa hus har hjul, de är husvagnar"  

Rep 14
Skriv ett program som finner det andra stället då strängen "hus" förekommer i texten "Vissa hus har hjul, de är husvagnar"

Rep 15
Skriv ett program som räknar ner från 10 till noll.

Rep 16
Skriv en if-sats som är sann om x är större än 5 men mindre än 10.

Rep 17
Skriv en if-sats som är sann om x är mindre än 5 eller större än 10.

Rep 18
Skriv en if-sats som är sann om x är större eller lika med 5 men mindre än 10.

Rep 19
Sktiv en if-sats som är sann om x är större än 5 eller mindre än 0 men skild från 10.

Rep 20
Skriv ett program som beräknar fakulteten av ett inskrivet positivt heltal. (Fakulteten för N är 1*2*3*...*N.)

tisdag 23 oktober 2012

Eclipse och PyDev

Installera Eclipse

Eclipse är ett professionellt utvecklarverktyg, även kallat IDE - Integrated Development Environment, som används vid programmering i många olika språk. Eclipse är opensource-programvara och fritt att använda.

Ladda ner och installera Eclipse
Du finner Eclipse i många olika versioner beroende på viket språk det i huvudsak är förberett för. Dock kan nya språk läggas till i efterhand vilket vi kommer att göra med Python. Jag rekommenderar att du laddar ner och installerar Eclipse IDE for Java Developers (32 bit).
  • Följ denna instruktion för installation på Mac punkt 1-7
  • Punkt 8 i instruktionen: När programmet första gången startar får du uppmaning att ange "workspace".  Huvudmappen för de filer du skapar i programmet. Ange samma mapp som du redan har dina programmeringsfiler i.
  • Fortsätt med punkt 9-11


Installera PyDev och konfigurera Python

För att programmera Python i Eclipse behöver du installera Python-perspektivet PyDev. Detta görs direkt i Eclipse. Följ instruktionerna på PyDevs hemsida under rubriken Installing with the update site.  Några förtydliganden:
  • Välj som på bilden  http://pydev.org/updates som uppdateringsställe.
  • I fönstret Available Software bockar du för PyDev
  • Så som beskrivs skall du i samma fönster avbocka: Contact all update sites during install to find required software.
Om inget fel uppstår skall du nu ha PyDev installerat

Konfigurera Python
Nu är det dags att konfigurera PyDev så det använder den interpreter du har för Python. (Den du tidigare använt för att köra dina program).
  • I Eclipse väljer du Preferences i menyn Window. Sedan PyDev, Interpreter  - Python.  Samt trycker på New...
  • I dialogrutan som kommer upp skriver du in ett lämpligt namn tex: Python3.2 Sedan trycker du på Browse...
  • På Mac hittar du interpretern här: (Se även denna instruktion)
  • Du bör ha ett fönster som liknar nedanstående efter dessa steg:
  • Tryck Ok
Eclipse ska nu vara färdig för att programmera i Python

Välj PyDev perspektivet
  •  I menyn Window väljer du Open perspective och Other...

  • Tryck Ok och du ska vara klar för att programmera.

Projekt och ett första program

 Då större program består av många filer skapar man projekt där filerna samlas. Skapa ett nytt projekt där du samlar filer du gör i Programmering 1.
  • Tryck på knappen New  och välj PyDev projekt. Se nedan. Tryck Next.
  
  •  Fyll i enligt nedanstående bild och tryck Finish.
  

Nu har du skapat Projektet Programmering 1 och de källkodsfiler (moduler) du skapar kommer att finnas i en undermapp kallad src.

Ett första program
Dags att testa att programmera i Eclipse
  • Högerklicka på ditt projekt (Programmering1) i fönstret till vänster. Välj New och PyDev Module.
  • Fyll i ett namn på modulen, tex: test, och tryck Finish
  • Nu öppnas filen redo för programmering med endast en inledande kommentar inskriven. Kommentaren är av typ docstring, en typ av kommentar som läses av automatiska verktyg som hjälper programmeraren att dokumentera arbetet. Låt den gärna stå kvar.
  •  Under kommentaren skriver du något enkelt program och trycker sedan på pilen i den gröna cirkeln. (Se även bild nedan)
  • Tryck OK i dialogrutan som kommer upp. Du vill köra Python Run alltså vanlig programkörning.
  • Du kan bocka för att automatiskt spara filer före körning så slipper du svara på denna fråga varje gång.
Förhoppningsvis fungerar allt och du får ett resultat som detta:

Slut.

torsdag 18 oktober 2012

Lösningsförslag repetitionsuppgifter del 1

Nedanstående är förslag på lösningar till repetitionsuppgifterna 1.1-1.10.

Rep 1.1

#Summan av två kastade tärningar
import random

t1=random.randint(1,6)
t2=random.randint(1,6)
print("Ögonsumman blir " + str(t1+t2))


Rep 1.2

#Medlet av inmatade tal
summa=0
antal=0

while True :
    try:
        n=float(input("n="))
        if (n == -1) : break
        summa=summa+n
        antal=antal+1
        print("Medlet=" + str(summa/antal))
    except ValueError:
        print("Felaktig inmatning")
print("Slut")

Rep 1.3

#Största av inskrivna positiva tal
storst=-1

while True :
    try:
        n=float(input("n="))
        if (n == -1) : break
        if storst < n : storst=n
        print("Medlet=" + str(summa/antal))
    except ValueError:
        print("Felaktig inmatning")
print("Största talet var: " + str(storst))



Rep 1.4

(x > 100 or x < 50) and x != 20

Rep 1.5

#Skriver ut talet, kvadraten och kuben för 1-20 i kolumner
for x in range(1, 21) :
    print("{:4d}{:6d}{:6d}".format(x, x*x, x*x*x))

Rep 1.6

#Skriver ut positionssiffrorna för ett heltal

tal = input("Skriv ett heltal: ")
nollor=len(tal)-1

#Går igenom tecken för tecken. Lägger till nollor enligt
#position från slutet för att skriva ut vilken plats siffran står på.
for s in tal :
    print("1"+"0"*nollor+"-talssiffran är "+str(s))
    nollor=nollor-1

Rep 1.7
Uttrycket not (not a and not b) ger samma resultat som a or b

Rep 1.8

#Kontrollerar om ett heltal är ett primtal
import math

a=int(input("Skriv ett positivt heltal: "))
rot=int(math.sqrt(a)) + 1
primtal=True

#Testar att dividera med alla tal upp till roten ur det
#inskrivna talet. Sätter primtal till falskt och hoppar ur om delbart.
for i in range(2, rot) :
    if a % i == 0 :
        primtal = False
        break

#Om primtal fortfarande är sant så har inget tal varit delare.
if primtal : print( str(a) + " är ett primtal")
else : print( str(a) + " är inte ett primtal")

Rep 1.9

#Simulerar sönderfall genom kast av många tärningar.
import random

n = 1000
k = 0

print("Kast  Antal")

#Loopar tills tärningarna är slut
while n > 0 :
    print("{:3d}{:8d}".format(k, n))
    #Kastar alla tärningar som är kvar efter förra omgången
    #Tar bort de som slår 6.
    for i in range(n) :
        if random.randint(1, 6) == 6 :
            n=n-1
    k = k +1

Rep 1.10
XOR kan skrivas som tex:

(a or b) and not (a and b) 

men det snyggaste sättet är:

a != b


Rep 1.11

#Hästkapplöpning med tärningskast. Först till 100
#Version med sammansatta logiska-satser
import random

hast1_position = 0
hast2_position = 0
vinnare=0

#Spelaren väljer häst
while True :
    try :
        val=int(input("Satsa på häst 1 eller 2: "))
        break
    except ValueError :
        print("Välj 1 eller 2 ")

#Här springer hästarna
print("Tryck enter för nytt tärningskast")
while hast1_position < 100 and hast2_position < 100 :
    print("Häst 1 har nått: " + str(hast1_position))
    print("Häst 2 har nått: " + str(hast2_position))
    hast1_position=hast1_position+random.randint(1,6)
    hast2_position=hast2_position+random.randint(1,6)
    input() #Tryck enter för varje "tärningskast"

#Vilken häst vann?
if hast1_position < 100 :
    vinnare=2
    print("Häst 2 vann")
elif hast2_position < 100 :
    vinnare=1
    print("Häst 1 vann")
else :
    print("Lika!")

#Vann spelaren?    
if (val == vinnare) :
    print("Du vann!")
else :
    print("Du förlorade")

tisdag 16 oktober 2012

Mer om kodning samt repetitionsuppgifter 1.2

Funktioner i funktioner

Redan i början av kursen introducerades en funktion som var innuti en annan funktion, så kallade nästlade funktioner. Nämligen:
 
vinkeln=float(input("vinkeln="))
 
Där funktionen input körs först och svaret direkt hanteras av funktionen float. Denna typ av skrivning är mycket vanlig för att slippa onödiga variabler. Alternativet skulle varit att först skapa en strängvariabel med input och sedan på en ny rad göra om den till ett tal:

s=input("vinkeln=")
vinkeln=float(s)

Något som ju är klumpigare både för programmeraren och datorn. Fram över kommer vi i högre utsträckning ha användning för denna typ av skrivning.

Metoder efter metoder

På liknande sätt som funktioner kan nästlas kan metoder skrivas efter varandra med punkt mellan. Nedanstående följd av metoder skriver ut "STOP" från texten "stopp":

"stopp".upper().replace("STOPP", "STOP")

Övning 1.39
Testa ovanstående i interaktiva skalet.

Funktioner i villkor

Det går även att använda funktioner som input direkt i ett villkor.

Övning 1.40
Använd interaktiva skalet och testa detta:
while input("Sluta? ") !="J" : print("Ett varv till")

Nyckel ordet pass

Det finns situationer då språket kräver att en sats finns men du inte vill att någon åtgärd görs. Då kan pass komma till användning. Ex:

while True :
    try:
        x=float(input("Skriv ett tal "))
        break
    except ValueError :
        pass

En annan användning av pass är som platshållare för icke implementerade delar av programmet medan du programmerar:

if slut_pengar :
    pass #Här ska något fiffigt göras

Bra kodstil

Alla språk har en praxis för hur man bör skriva koden. Att följa denna hjälper dig själv och andra att läsa din kod. Här följer bra praxis för Python:
  • Använd 4 mellanslag för indrag, inte tab.
  • Använd radbrytning så att raderna inte blir längre än 79 tecken. Detta underlättar läsning och man kan ha flera filer kod bredvid varandra på skärmen.
  • Använd blankrader för att separera kod i stycken. Dela efter sammanhängande innehåll.
  • Initiera variabler och konstanter i början av den kod där de används när så är möjligt.
  • Sätt i första hand kommentarer på en egen rad. Undvik placeringar i slutet av längre kodrader.
  • Använd dokumentationssträngar. Vi återkommer till dem och mer om koddokumentation senare i kursen.
  • Använd mellanslag runt operatorer och efter komma, men inte direkt efter eller före parenteser. Ex: a = f(1, 2) + g(3, 4).
  • Namnge variabler, funktioner mm. så att dess syfte och funktion framgår.
  • Namnge variabler, funktioner och klasser på ett konsistent sätt. Variabler, funktioner och metoder skrivs med sma_bokstaver_och_streck_mellan_orden.  Klasser skrivs MedStorForstaBokstav och ihopskrivna ord.
  • Använd self som namn på det första metodargumentet. Vi återkommer till detta.
  • Använd inte udda tecken i koden. För namn på variabler mm bör du hålla dig till Aa-Zz samt 0-9

Repetitionsuppgifter 1.2


Rep 1.4
Skriv ett logiskt uttryck i Python som returnerar True om talet x är: Större än 100 eller mindre än 50 men inte 20.

Rep 1.5
Skriv ett program som gör en tabell med kolumner för talet, talets kvadrat och kub (upphöjt till tre) för talen 1 till och med 20.

Rep 1.6
Skriv ett program som talar om värdesiffrorna i ett heltal som användaren matar in.
Exempel på utskrift:
Skriv ett heltal 1234
1000-talssiffran är 1
100-talssiffran är  2
10-talssiffran är 3
1-talssiffran 4

Tips: Behandla talet som en sträng

Rep 1.7
Använd interaktiva skalet och testa följande logiska uttryck: not (not a and not b)
Sätt in olika kombinationer av True och False i stället för a respektive b.
Påminner resultaten om något annat logiskt uttryck?

Rep 1.8
Skriv ett program som talar om om ett inmatat tal är ett primtal. Se nedanstående pseudokod för programmeringstips.

input tal
beräkna roten ur talet avrundat till närmaste högre heltal
Sätt primtal=True
för alla tal mellan 2 och roten ur talet :
    om delbart sätt primtal=False och hoppa ur loopen
skriv ut om det är ett primtal eller inte

Rep 1.9
För att simulera radioaktivt sönderfall brukar man kasta ett större antal tärningar i flera omgångar och efter varje kast plocka bort sexorna och räknar hur många tärningar som är kvar. Skriv ett program som gör motsvarande simulering. Se pseudokoden nedan:

sätt antal tärningar till 1000
sätt antal kast till noll
medan det finns tärningar kvar:
    skriv ut antal gjorda kast och antal tärningar som är kvar
    för varje tärning som är kvar:
         slumpa ett heltal 1 till och med 6 och om det blir 6 ta bort en tärning.
    öka antal kast med ett


Rep 1.10
Inom logik används ibland a XOR b. Där XOR är förkortning för exlusive or. Denna operation returnerar sant om antingen a är sant eller  b är sant men inte om båda är sanna. Skriv ett logiskt uttryck i Python som motsvarar XOR.
Tips: Det finns ett fiffigt sätt!

Rep 1.11
Skriv ett program där två "hästar" tävlar mot varandra genom att ta slumpade steg som i uppgift 1.3. Användaren satsar på en av hästarna före start och får sedan reda på om hen vann eller förlorade när "hästarna gått i mål. 

Resultat av Rep 1.9 plottat med GNUplot

onsdag 10 oktober 2012

for-loopen

En annan viktig loop är for-loopen. Den används när man vill upprepa en loop ett bestämt antal gånger eller gå igenom en uppsättning data. Vi tittar på några varianter av denna.

Övning 1.33
Testa denna variant av for-loop:
Tips: Om du vill kan du använda interaktiva skalet och skriva hela loopen på en rad. 
 
for i in range(5) :
    print(i)


Hur det fungerar:
  • Funktionen range(5) skapar en lista med fem heltal [0, 1, 2, 3, 4]. Notera att det första talet är 0 och det sista 4.
  • Variabeln i sätts lika med första värdet i listan, alltså 0.
  • Satsen i loopen utförs.
  • Variabeln i sätts till lika med nästa värde i listan och loopen börjar om tills listan är slut.
 Notera: Precis som i while-loopar kan break användas för att hoppa ur en for-loop.

 Varianter på range()

  • range(a) skapar en lista heltal från och med 0 till och med a-1
  • range(a, b) skapar en lista heltal från och med a till och med b-1
  • range(a, b, c) skapar en lista heltal från och med a till b med steg c
Övning 1.34
Gör om övning 33 men ange:
a) range(-5, 5)
b) range(20,  200, 50)
c) range(10, 0, -1)

Uppgift 1.10
Skriv ett program som talar om vilka tal ett givet heltal är jämnt delbart med.
Tips: Ett tal kan endast vara jämnt delbart med tal mindre än eller lika halva talet. Du behöver bara testa upp till hälften (avrundat uppåt).

Loop i loop

Det går utmärkt att sätta loopar inuti andra loopar. Nedanstående visar hur man kan få fram en multiplikationstabell genom denna metod.

Övning 1.35
Skriv och testa. Tänk efter ordentligt så du säkert förstår vad som händer.

#Multiplikationstabell

for i in range(1,11) : # yttre for-loop för vänstra talet i mult.
    for j in range(1,11) : # inre for-loop för högra talet i mult.
        print("{:0d}*{:0d}={:0d}".format(i,j,i*j), end="\t")
    print() # Ny rad
    print() # Tomrad mellan varje nytt vänstertal

Notera: I vanliga fall blir det automatiskt ny rad efter en print-sats. Detta kan vara opraktiskt när man vill skriva ut listor. Det går att göra så att detta inte sker genom att använda en variant av print där man anger vad som ska vara avslutning av utskriften. Satsen print( "xxx", end="\t") skriver ut xxx men avslutar med tab istället för ny rad. För att få ny rad kan ett tomt print() användas.

Nyckelordet continue

Vi har tidigare lärt oss satsen break som hoppar ur en loop. Ett användbart alternativ till break är continue som gör att programmet går vidare direkt till nästa varv i loopen. Se nedanstående övning:

Övning 1.36
Skriv och testa

for num in range(2, 10):
    if num % 2 == 0:
        print("Fann ett jämnt tal ", num)
        continue
    print("Fann ett ojämnt tal ", num)

Notera: continue går även att använda i while-loopar


Inlämningsuppgift 1.4
Ändra uppgift 1.10 så att den skriver ut delbarheten för alla talen 1 till och med 20.

Forsatsen med texter

I Python och flera andra språk kan for-satser användas för att iterera över inte bara en lista med tal utan också andra följder. Till exempel kan for användas för att stega sig genom en sträng. Ex:

for s in "Python" : print(s)

Övning 1.37
Skriv ett program med for-sats som sätter punkt efter varje bokstav i en inmatad sträng och skriver ut resultatet. Ex: "SWAT" blir "S.W.A.T."

Itereringen över en sträng går alltid från första till sista tecknet. Om du vill iterera i en annan ordning, över delar av strängen eller behöver få reda på index för tecknen så får du skapa en range-funktion enligt nedastående övning.

Övning 1.38
Följande skriver ut en inmatad text baklänges

text = input("Skriv en text: ")
for i in range(len(text), 0, -1) :
    print(text[i-1], end="")


Notera:
Stegningen -1 i range-funktionen för att gå från högre till lägre index.
Användningen av i-1 då range går från och med len(text) till 0 medan index går från och med 0 till och med len(text)-1.
Tillägget end="" i print-satsen för att undvika ny rad mellan tecknen.

tisdag 2 oktober 2012

Backslash på Mac i IDLE

Se instruktion av Malin Christersson:

Hur man skriver backslash "\" i IDLE med ett icke-amerikanskt Mac-tangentbord

Den vanliga knapp-kombinationen Alt+Shift/ resulterar troligen inte i någonting om man skriver den i IDLE på ett icke-amerikanskt Mac-tangentbord. För att få backslash att fungera måste man göra följande:
Välj IDLE->Preferences... och markera Keys-fliken. Gå ner till "expand-word"-raden och klicka på "Get New Keys for Selection"-knappen.
image
Välj några nya tangenttryckningar för "expand-word" och klicka Ok.
image
Skriv in ett namn för en ny "Custom Key Set".
image

Strängar

Variabeltypen string används för att lagra och manipulera text och textliknande teckenföljder.

En sträng anges omgiven av "-tecken eller '-tecken:
a="Hej!"
b='Hej!'

Speciella tecken

Tecknet \ ("backslash") är en så kallad escape character som används för att skriva tecken som annars skulle vålla problem då de krockar med hur koden normalt läses av programmet ex:
\"     ett "-tecken inuti en sträng omgiven av "-tecken
\'      ett '-tecken inuti en sträng omgiven av '-tecken
\n    ny rad
\t     tabulering

Hur skrivs då \  i en sträng? Jo som \\

Övning 1.23
Använd det interaktiva skalet och testa följande:
a) print("C:\\kalle\\Python")
b) print("Lars kallas \"Lasse\"")
c) print("Kalle\t200\nLisa\t1200")

Långa rader i koden

Det är  rekommenderat att ha radlängder på max 79 tecken i koden för att förenkla för den som ska läsa och klara alla editorer. Därför kan det finnas behov av att dela upp en sats eller en sträng i flera rader.
  • För uttryck som inte är strängar och som omges av (), [] eller {} görs radbyte genom ENTER
  • För att byta rad i strängar eller uttryck utan omgivande parenteser används \
Övning 1.24
Testa exemplet:

lang_text="Detta är en låg text så jag byter \
rad i koden trots att det är en rad utskriven."
print(lang_text)
print()
print( "Och nu blev den ännu längre: " +
       lang_text + " Så den inte får plats på en rad")

Manipulera strängar

Strängar (eng. strings) kan ses som en rad tecken efter varandra. I Python är tecknen numrerade från noll och uppåt till sista tecknet. Positionen för ett tecken kallas index. Sista tecknet i en sträng har index som är 1 mindre än strängens längd.

Funktionen len(s) ger längden på en sträng.

 För att komma åt delar av en sträng används:
Uttryck Beskrivning
s[i] Returnerar tecknet med index i
s[i:j] Returnerar strängen från och med i till (men ej lika med!) j
s[i:] Returnerar strängen från och med i
s[:i] Returnerar strängen till i
s[-j] Motsvarar s[len(s)-j]. Alltså tecknet j från slutet
s[-j:] Returnerar resten av strängen från och med tecknet j från slutet
s[:-j] Returnerar strängen fram till tecknet j från slutet


Obs! Att använda negativa index som i de tre sista varianterna är en indexering som många språk saknar. Det finns tex. varken i C, C++ eller Java.

Övning 1.25
Skriv och testa nedanstående program.

text="ABCDEFGHIJK"
print(text+"\tLängd="+str(len(text)))
print(text[2])
print(text[len(text)-1])
print(text[2:6])
print(text[2:])
print(text[:6])
print(text[-2])
print(text[-2:])
print(text[:-6])

Concatenering, att lägga ihop strängar

Att lägga strängar efter varandra till en ny längre sträng kallas concatenring (eng. concatenate) och görs med + så som du sett. Det går också att skapa en upprepad sträng med *-tecken.

Övning 1.26
Använd interaktiva skalet och testa följande:
a) print("husvagn"[:3]+"lastbåt"[-3:])
b) print("Ha"*5)

Du kan inte ändra i en sträng

Det går inte att ändra i en sträng, lägga till eller ta bort tecken efter att den skapats. Utan du måste skapa en ny sträng för detta  och tilldela den till den ursprungliga. Ex:

Lägga till sträng t först till s
s=t+s


Lägga till sträng t sist till s
s=s+t

Lägga till t vid index j
s=s[:j]+t+ s[j:]

Ta bort en del av s från och med index i till j
s=s[:i]+s[j:]

Uppgift 8
Skriv ett program som testar ovanstående strängmanipulationer. Välj själv lämpliga strängar för t och s.

Jämförelse av strängar och några bra strängmetoder

Att jämföra strängar i Python påminner om jämförelser mellan tal. Här följer de mest användbara jämförelserna:
Uttryck Beskrivning
s == t Sant om s är exakt lika som t
s != t Sant om något skiljer mellan s och t
s in t Sant om strängen s återfinns någonstans i t
s not in t Sant om strängen s inte återfinns någonstans i t


Notera: Det är skillnad på stora och små bokstäver när jämförelser sker.

Strängar är lite av både fågel och fisk i Python, och flera andra språk. De fungerar som vanliga variabler men de är också objekt. (Vi kommer att tala mycket mer om objekt senare i kursen.)

Så som objekt har strängar metoder som kan användas för att utföra olika åtgärder. För att använda en metod skrivs strängen eller strängvariabeln följt av . och sedan metoden. Ex:
"Hej".lower()
s.lower()
Den övre raden ändrar strängen "Hej" till "hej" den nedre gör motsvarande för innehållet i strängen s.

Följande strängmetoder är ofta användbara:
metod Beskrivning
lower() Returnerar en sträng där alla bokstäver ändrats till gemener
upper() Returnerar en sträng där alla bokstäver ändrats till versaler
find(t)     Returnerar första index då strängen t återfinns. Om ingen hittas returneras -1.
count(t)     Returnera hur många gånger strängen t återfinns.
replace(s, t) Returnerar en sträng där alla förekomster av av strängen s bytts ut mot strängen t
strip() Returnerar en sträng där eventuella mellanslag först eller sist är borttagna
zfill(x); Returnerar en sträng där nollor fyller ut  till vänster om texten tills längden är x. Ex. "23".zfill(4) ger "0023"
format(a, ka) Strängformatering. a och ka är argument som används vid formateringen.

split(t)
Skapar en lista av strängar från den ursprungliga strängen. Uppdelade där strängen t förkommer. Mer om detta senare i kursen.


Överkurs: Detta är endast ett litet urval metoder och varianter på metoder. Läs mer här.

Övning 1.27
Testa följande program

s="IKEA"
t=s.lower()
print("s är: "+ s+"\nt är: "+t)

Notera att s behåller sitt värde "IKEA" .
Ändra programmet så att det byter "IKEA" i s till "ikea" istället för att skapa den nya variabeln t.


Övning 1.28
Ett program som summerar inskrivna tal och avslutas när man skriver n eller N. Skriv och testa.

sum=0

while True :
        try: 
            s=input("Skriv in ett tal. (n för att sluta) ")
            if s == "n" or s == "N": break
            sum=sum+float(s)
        except ValueError:
            print("Felaktig inmatning. Försök igen") 

print("Summan blir:" + str(sum))

Övning 1.29
Skriv ett program som returnerar första ordet ur en inskriven text.

Övning 1.30
Skriv ett program som skriver ut en inmatad sträng enligt nedanstående exempel:
Inmatad text: Hej alla glada
Utskrift:
H
He
Hej
Hej 
Hej a
... osv ...
Hej alla glad
Hej alla glada

Notera: Kontrollera så att programmet klarar strängar med ett tecken och att du inte får tomrad först i utskriften.

Övning 1.31
Skriv ett program som byter ut alla förekomster av hon och han till hen i en inmatad text.

Uppgift 1.8
Skriv ett program som skriver ut varje ord i en inmatad sträng på en egen rad.

Strängformatering

Det finns en mängd möjliga formateringar med hjälp av format-metoden. Vi ska titta på några. Syntaxen för strängformatering visas i följande exempel:

"Här är ett tal {0:0.2f} och här är ett tal {1:0.5e}".format(3454564, 3555564)

Resultatet blir (vilket du kan kontrollera med interaktiva skalet):

Här är ett tal 3454564.00 och här är ett tal 3.55556e+06

Klamrarna {} är platshållare som fylls i med innehållet från parentesen efter format.
Texten i klamrarna är en kod som talar om hur formateringen ska ske. Se nedanstående bild som visar vad de olika delarna betyder:

Notera: koden ovan är inte fullständig. Det finns ytterligare positioner som kan användas. Den täcker dock det viktigaste.
  • Index i formatlistan: Anger vilken position i parentesen, räknat från noll, som innehållet ska hämtas ur. Kan utelämnas. Om det utelämnas hämtas innehållet i ordningen de står i format-parentesen så att första klamern fylls med första innehållet, andra med andra osv.
  • Minimal längd: Anger det minsta antal tecken som innehållet ska ta upp. Om det blir tecken över fylls de med mellanslag. Kan utelämnas.
  • Precision: Anger antal decimaler eller värdesiffror för tal. Kan utelämnas.
  • Formateringstyp: Ytterligare information om formateringen för tal. Se nedanstående tabell för exempel.
Tecken Beskrivning
b För heltal: Binär form
d Heltal: Basen 10
f Flyttal: Bestämt antal decimaler och utan tiopotens
g Flyttal: Automatiskt byte till grundpotes för stora  eller små tal. När g används anger siffran bakom punkten antalet värdesiffror.
e Flyttal: Grundpotensform
x För heltal: Hexadecimal form


Övning 1.32
Använd interaktiva skalet och gör följande:
a) Skriv och testa: "{:6.2f}".format(3.1415)
b) Skriv och testa: "{:10}{:6d}".format("Invånare", 123)
c) Ta reda på vad 2000 blir hexadecimalt respektive binärt.
d) Skriv och testa: "{1}={0:0.3g}".format(12.234, "a")

Uppgift 1.9
Skriv ut ett "kvitto" enligt nedanstående. Decimalpunkterna ska hamna under varandra.

Godis      21.40
Kött      121.30
 ===============
Summa     142.70   

onsdag 26 september 2012

Mer om logiska uttryck och elif-satsen

Vi ska nu titta på mer komplicerade logiska uttryck.

Minns att vi har en logisk datatyp som kallas bool som kan ha två olika värden. Sant, True, och falskt, False.
En jämförelse som x>5 resulterar i ett svar av typen bool; True om x är större än 5 och False annars.

And, or och not

För att kombinera olika jämförelser används de logiska operatorerna: and (och), or (eller) och not (icke).
Om A och B är bool fungerar de som i tabellerna nedan:

A B A and B
False False False
False True False
True False False
True True True
Både A och B måste vara sanna för att A and B skall bli sant


A B A or B
False False False
False True True
True False True
True True True
Minst en av A eller B måste vara sann för att A or B skall bli sant

A not A
False True
True False

Övning 1.18
Använd det interaktiva skalet för att pröva de logiska operatorerna. Pröva med följande:
a) True and False
b) True or False
c) not False
d) 3 > 2 or 2 > 3

Prioriteringsregler

Liksom i vanliga matematiken, där tex.  * görs före +, finns det prioriteringsregler för logiska operatorer. Se följande tabell som går från högsta till lägsta av de vi kommit i kontakt med:
Prioritet Operatorer
1 ()
2 vanlig matematik
enligt dess regler
3 jämförelser: >, <,
 ==, !=, >=, <=
4 not
5 and
6 or

I övning 1.18d görs alltså jämförelserna 3>2 som blir True och 2>3 som blir False först. Sedan True or False som blir True.

Notera:
or görs efter and
not görs före både and och or

Övning 1.19
Använd det interaktiva skalet för att pröva de logiska operatorerna. Pröva med följande:
a) not True and False
b) not (True and False)

Varför blir det skillnad mellan resultaten?

Övning 1.20
Skriv och testa följande program:

while True :
    try : 
        a=int(input("Skriv ett tal "))
        if a < 100 and a > 50 :
            print("Du skrev ett tal mellan 50 och 100")
    except ValueError:
        print("Tack för mig")
        break


Uppgift 1.7
 Ändra det logiska uttrycket i if-satsen i övning 1.20 så den talar om om man skriver tal som antingen är större än 100 eller mindre än 50.

elif-satsen

En if-sats kan följas av en eller flera elif-satser, förkortning för "else if". Detta är användbart i många sammanhang.

Övning 1.21
Skriv och testa:

while True :
    try : 
        a=int(input("Skriv ett tal "))
        if a > 100 : print("Du skrev ett tal större än 100")
        elif a > 50 :
            print("Du skrev ett tal mellan 50 och 100 (inkl.)")
        else : print("Du skrev ett tal mindre än 50")
    except ValueError:
        print("Tack för mig")
        break
 
Funktion:
  • Först utförs testet i if-satsen. Om det är sant görs följande print-sats sedan hoppar programmet över följande elif och else. Annars går programmet vidare till elif-satsen.
  • Om if-satsen svarade falskt utförs testet i elif-satsen. Om det är sant görs följande print-sats sedan hoppar programmet över följande else. Annars går programmet vidare till else-satsen.
  • Om inte if- eller elif-satsen var sann görs satserna efter else.
Övning 1.22
Skriv ett program som talar om om ett inmatat heltal är jämnt delbart med 2, 3 eller 5. Tips: Se övning 1.10.

onsdag 12 september 2012

Månlanda


Månlanda är ett enkelt och klassisk spel inspirerat av Apollo-programmet. Spelaren ska landa en månlandare på månen. När spelet startar är landaren på väg ner och spelaren kan reglera bromsraketernas gaspådrag en gång per sekund för att landa mjukt. Dock har landaren begränsad mängd bränsle så det gäller att inte slösa.

Spelfysiken

Spelet bygger på Newtons fysik och rörelseformlerna som du mött i fysikkurserna.

Spelets simulering tar tidssteg på en sekund och acceleration, hastighet och höjd beräknas för varje tidssteg.

Månens gravitation är inte lika stark som på jorden utan tyngdaccelerationen är ungefär en sjättedel av den på jorden. I spelet kan det vara bekvämt att sätta tyngdaccelerationen lika med 1,5 m/s2.

Bromsraketerna motverkar tyngdaccelerationen. Accelerationen under ett tidssteg kan skrivas som:

a =  fK - G                                     (Ekv. 1)

Där f är bränsleflödet i liter per sekund, K en konstant och G månens tyngdacceleration. Konstanten K är ett mått på kraften från motorn, vid pådraget 1 l/s, i förhållande till landarens massa. Notera att positiv acceleration är uppåt då höjden ökar åt det hållet.

Hastigheten ändras alltså med a under ett tidssteg:

vt = vt-1 + a                                 (Ekv. 2)

Där vt är den nya hastigheten och vt-1 är hastigheten förra tidssteget.

Höjden kommer att ändras med medelhastigheten under tidssteget:

ht = ht-1 + (vt + vt-1) / 2            (Ekv. 3)

vilket kombinerat med Ekv. 2 blir

ht = ht-1 + vt - a/2                     (Ekv. 4)


För varje nytt tidssteg beräknas alltså:

a =  fK - G

vt = vt-1 + a 

ht = ht-1 + vt - a/2


Gaspådrag och bränsle

Varje nytt tidssteg börjar med att spelaren anger det valda gaspådraget f. Gaspådraget har ett maximalt värde, full gas, som spelaren inte kan överskrida. Naturligtvis kan spelaren inte ange negativt gaspådrag eller använda mer än det kvarvarande bränslet.

Vid varje tidssteg minskas kvarvarande bränsle med pådraget f:

bt = bt-1 - f

Där bt är kvarvarande bränsle.

Landningen

När höjden är noll, eller mindre, sker landningen...eller kraschen. Om farten då är mindre än 2 m/s, alltså vt > - 2 , så anses landningen lyckad annars är det en kraschlandning.

Flödesschema

Nedanstående visar ett förslag på flödesschema för programmet:

Lämpliga startvärden

Följande värden är lämpliga för att få ett fungerande spel:
Tyngdacceleration G=1,5
Full gas MAX=60
Konstant K=0,1
Bränslemängd b=600
Starthöjd h=500
Starthastighet v=-10

Inlämningsuppgift 1.3

Skapa spelet Månlanda och skicka in. Tänk på att hantera eventuella undantag.

Tips: När du fått spelet att fungera så kan du testa olika värden på bränslemängd eller andra variabler för att göra spelet lagom svårt.

Tips: Som standard skrivs alla decimaler ut för höjd och hastighet och bränsle. Detta kan leda till svårlästa rader. Det går att få en snyggare formatering med tex två decimaler genom att använda formaterings-funktionen för texter:

print("Höjd= {0:.2f}".format(h))

Om h=2.248432 ger ovanstående texten: Höjd= 2.25


Överkurs: Läs mer om textformatering här och se om du ytterligare kan snygga upp utskrifterna.

tisdag 11 september 2012

Repetitionsuppgifter 1.1

Dessa uppgifter repeterar tidigare kunskaper. Göres i mån av tid på lektionen eller som repetition hemma.

Rep 1.1
Skriv ett program som simulerar kast med två vanliga tärningar och visar ögonsumman.

Rep 1.2
Skriv ett program som beräknar medelvärdet av inmatade positiva tal. Efter varje nytt tal användaren skriver in ska medelvärdet av de inskrivna talen skrivas ut. Avslutas genom att användaren skriver in -1.

Rep 1.3
Skriv ett program som i repetitionsuppgift 1.2 men som efter avslutat inskrivande skriver ut det största av de inmatade talen.

söndag 9 september 2012

Fel och undantag

Det finns tre grundtyper av fel i programmeringssammanhang:
  • Syntax-fel: Fel i källkoden pga stavfel eller felaktig satsbyggnad
  • Buggar: Fel i källkoden så att programmet inte uppför sig som förväntat
  • Undantag (eng. Exceptions) Fel av typen division med noll, inmatning av text när en siffra förväntas mm.
Syntaxfelen brukar upptäckas av skalet du använder för att skriva ditt program. Buggar är upp till dig som programmerare att leta efter och rätta. För små program är det ofta enkelt att finna dem men för större kan det vara mycket svårt.

Undantag kan även beskrivas som förväntade problem. Sådant som du när du programmerat räknar med kan hända. Till exempel att någon råkar trycka ENTER istället för att skriva in ett tal. Det är att hantera undantag vi ska titta på här.

try-satsen

Satsen try används för att hantera förväntade problem. De består av två delar try och except.  Se nedanstående exempel:

Övning 1.15
Skriv följande program som hanterar division med noll och testa funktionen

a=float(input("nämnaren="))
try :
    print(100/a)
except ZeroDivisionError :
    print("Division med noll")
print("Tack för mig")

Hur det fungerar:
  • Först utförs de indragna satserna mellan try och except.
  • Om inget undantag inträffar hoppas de indragna satserna efter except över och programmet går vidare vid print("Tack för mig") .
  • Om ett undantag inträffar vid någon av satserna mellan try och except så hoppar programmet direkt till except. Där kontrolleras om undantaget är av den klass (typ) som beskrivs av nyckelordet ZeroDivisionError. Om så är fallet utförs de indragna satserna efter except. Texten "Division med noll" skrivs ut. Sedan fortsätter programmet till sitt slut.
  • Om ett undantag inträffar av en annan klass än ZeroDivisionError kommer programmet att hantera detta på standardsätt. Alltså programmet avslutas med ett felmeddelande.


Övning 1.16
Kör programmet i övning 1.15 och skriv in en bokstav istället för ett tal.

Notera att programmet nu avslutas med ett felmeddelande och sista raden inte körs. Du har nu skapat ett icke hanterat undantag (eng. unhandled exception).

Några undantagsklasser

Det finns en stor mängd färdigdefinierade undantag i Python. De är också ordnade i en hierarki med vissa undantag som är generella och täcker in flera underklasser.

Klass Beskrivning
Exception Huvudklassen för alla undantag. Används med försiktighet för att fånga upp undantag. Använd i första hand mer specifika klasser i stället.
IOError Undantag vid tex. läsning av och skrivning till filer.
IndexError Undantag vid hantering av listor och dylikt. Mer om detta senare i kursen
TypeError Undantag då typen är fel för operationen/fuktionen.  Tex: print("a"+2).
ValueError Undantag vid ogiltigt värde. Tex. math.sqrt(-2)
Även försök att omvandla en sträng bokstäver till tal med float() och int(). Se nedan övning 17
ZeroDivisionError Undantag vid division med noll.

Det går att ha flera olika klasser av undantag listade efter except. Man sätter de då inom parentes och med komma mellan dem. Till exempel kan det ibland vara bra att hantera matematiska fel med:

except (ValueError, ZeroDivisionError) :


Överkurs: Läs mer om undantag och hierarkin. Följ länkarna i texten ovanför tabellen.

Överkurs: Det går att ha flera except i en och samma try-sats för att hantera olika undantag. Läs om detta här.

Övning 1.17
Denna övning visar hur man skriver ett program som hanterar inmatning så att frågan upprepas tills användaren matar in korrekt datatyp. Skriv och testa.

while True :
    try :
        a=float(input("Skriv en siffra "))
        break
    except ValueError :
        print("Ooops! Ej ett tal")
print("Du skrev " + str(a))

Programmet snurrar i while-loopen om det blir ett undantag i tilldelningen av a. Om tilldelningen sker korrekt når programmet break-satsen och hoppar ur loopen  till sista raden.

Uppgift 1.5
Skriv om inlämningsuppgift 1.2, andragradsekvationsprogrammet, så att det hanterar felaktiga värden vid inmatning (så som text eller bara ENTER) samt använder undantag istället för if-sats för att hantera negativa rötter.

Uppgift 1.6
Då man ska mata in många värden är det extra viktigt att använda undantagshantering. Ingen vill mata in 143 värden och sedan kraschar programmet pga att man råkar trycka fel vid det 144...
Skriv om uppgift 1.4 så att felaktiga inmatningar hanteras. Tips: det går att utnyttja den oändliga loopen som redan finns för att effektivt genomföra detta.

tisdag 4 september 2012

While-loopar

I en loop upprepas samma satser flera gånger. Vi ska här se på en av två vanliga loopar nämligen while-loopen

While-loopen

While-loopen upprepar satserna i loopen tills logiska uttrycket i while-satsen inte är sant. Precis som för if-satser används indrag för att markera vilka satser som ska loopas:

while logiskt uttryck:
   sats(er) 

Övning 1.12
Skriv och testa följande program.
#Gissa tal

import random #modulen random gör så att jag kan generera slumptal

a = random.randint(1, 10) #Genererar ett slumpmäsigt heltal 1 till 10
b = 0                     #Initierar gissat tal utanför intervallet
gissningar = 0            #Antal gjorda gissningar 
while a != b :
    b = int(input("gissa talet:"))
    gissningar = gissningar + 1 #Ökar antalet gissningar med 1
print("Du gissade rätt på " + str(gissningar) + " försök")

Det finns några saker att notera i detta program:
  • Användningen av random.randint(1, 10) som generar ett slumpat heltal från och med 1 till och med 10. Läs gärna mer om generering av slumptal här.
  • Initieringen av b före loopen. Variabeln b sätts till 0 som är utanför intervallet för slumptalet. Vad kunde ha hänt annars?
  • Initieringen av gissningar till 0 då den kommer att ökas med 1 efter den första gissningen.
  • Tilldelningen gissningar=gissningar+1 gör att gissningar ökas med 1 efter varje gissning. Lägg märket till att denna typ av =-användning är felaktig matematiskt men vanlig inom programmering.
Överkurs: Tilldelningen a = a + 1 kan skrivas mer kortfattat med operatorn += så som a += 1 . Ändra i programmet så att denna operator används.

Övning 1.13
Ändra programmet i övning 1.12 så att ett slumpat heltal mellan 1 och 100 genereras samt att användaren får reda på om gissningen var större eller mindre än rätt svar efter varje gissning.

Uppgift 1.3
Skriv ett program som för varje varv i en loop genererar ett slumpat heltal 1 till 6 och adderar det med föregående tal samt skriver ut summan. Programmet ska loopa tills summan blivit minst 100.


Oändlig while-loop och break

Nedanstående är en oändlig loop.

while True :
    print("loop the loop")

OBS! Ovanstående köres på egen risk. Prova ctrl+C för att bryta loopen men inga garantier ges.

Dessa kan vara användbara ibland men vanligen vill man ha något sätt att bryta loopandet. Då kommer kommandot break till hjälp. Med break bryts loopen och programmet fortsätter nedanför loopens satser.

Kommandot break kan användas i alla loopar för att hoppa ur loopen.

Övning 1.14
Skriv programmet nedan och testa funktionen

while True :
    a=int(input("Skriv in ett tal. (0 för att sluta) "))
    if a == 0 : break
print("Du skrev noll. Avslutar")

Uppgift 1.4
Genom att  använda en oändlig loop samt break  i stället för att göra testet om gissningen är korrekt i while-satsen kan programmet i övning 1.13 skrivas kortare och med färre variabler. Gör det.

tisdag 28 augusti 2012

Enkla villkor

Räkna med logik

 

Övning 1.6
Direkt i interaktiva fönstret skriver du
3>2
Vad blir svaret?
Skriv nu
2>3
Vad blir svaret?

Svaret True eller False är en ny typ av variabel som heter boolean, förkortas bool i Python. En boolean kan anta två värden: sant eller falskt.

Logiska symboler

Följande symboler används vid logiska jämförelseoperationer
Betydelse Matematik Python
Mindre än < <
Större än > >
Mindre än eller lika <=
Större än eller lika >=
Lika = ==

Skilt från
!=
OBS! Notera == tecken för jämförelse lika med. Vanligt fel att råka använda enkelt lika med istället.

Notera att jämförelsen == mellan två flyttal (float) kräver att de är exakt lika på sista decimalen för att jämförelsen ska vara sann.

Notera även att jämförelse av strängar fungerar på ett annat sätt än tal. Vi återkommer till det.

Övning 1.7
Pröva genom att i interaktiva skalet skriva olika jämförelser med tecknen ovan. Tex: 4 != 3
Visst fungerar det som du tänkt.


Genomgång av if-satsen


If-satsen


If-satser i Pyton skrivs:

if logiskt uttryck : sats

eller

if logiskt uttryck :
    Indragen sats 1
    I
ndragen sats 2
    ...
else :
    I
ndragen sats 1
    I
ndragen sats 2
    ...


Viktigt! Det är indragningen som gör att Python vet vilka satser (rader) som ska köras om if-satsen är sann respektive inte. Du måste använda indragna rader - och det är bra programmeringspraxis också!

De indragna raderna bildar ett block.

Övning 1.8
Skriv följande program och testa funktionen

vikt = float(input("Hur mycket väger din väska i kg? "))
if vikt > 25:
    print("Det kostar 100 kr extra för så tungt bagage.")
print("Välkommen åter.")


Övning 1.9
Skriv följande program och testa funktionen

temperatur = float(input("Vad är temperaturen? "))
if temperatur > 15:
    print("Välj shorts.")
else:
    print("Välj byxor.")
print("Dags att springa en runda.")

Uppgift 1.2
Testa i interaktiva fönstret vad som händer om du skriver följande if-satser.
Notera: Du behöver trycka ENTER två gånger för att if-satsen skall köras. Första ENTER gör att skalet väntar på om du ska skriva else eller en ny rad i satsen.

if True : print("sant")
Testa nu
if False: print("falskt")

Förklara resultatet för mig.

Övning 1.10
 Tecknet % ger resten vid division även kallat modulo - alltså är tex. 9 % 4 = 1. Använd detta för att skapa ett program som talar om för användaren om ett tal hen matat in är jämnt delbart med 7. Programmet skall svara med antingen "n är jämnt delbart med sju" eller "n är inte jämnt delbart med sju". Där n är talet användaren angav.

Övning 1.11
Komplettera övning 1.10 så att användaren förutom svaret ovan får reda på hur många gånger sju får plats i det angivna talet. Detta oberoende om det är jämnt delbart eller ej. Tips: Använd gärna //

Inlämningsppgift 1.2
Komplettera programmet i inlämningsuppgift 1.1 så att användaren får svaret "Ekvationen saknar reella rötter" om så är fallet.


söndag 26 augusti 2012

Ett första program

DEL 1

Förberedelse

Källkoden till dina program sparas i filer med ändelsen .py. IDLE sparar som standard filerna i din Dokument-mapp. Men för att hålla reda på dina filer i kursen skapar du en undermapp i Dokument med namnet "Programmering1" (ej mellanslag) som du använder fram över.

Överkurs: Du kan se till att din mapp öppnas som standard genom denna metod. Det förenklar framöver.

Enkla program

För att skriva ett program i IDLE så skapa ett nytt fönster i Fil-menyn.

Övning 1.1
Skriv i det nya fönstret
 
print ("Hej världen")

Färgerna talar om hur Python tolkar det inskrivna. De hjälper dig att se om du skrivit rätt syntax.

Välj Run module, menyn Run eller F5.
Före körning måste du spara programmet. Spara som Ovn1.py i din mapp.
Se i huvudfönstret att det fungerade och skrev "Hej världen".

Övning 1.2
Skriv ett nytt program Ovn2.py enligt nedan

a=2
b=3
c=a+b
print(c)

Kör och kontrollera att det fungerar.


Genomgång olika variabler och input


Program med input


Övning 1.3
Skriv en snyggare version, som även är kommenterad, av övning 2 som Ovn3.py enligt nedanstående
a=2 #Första termen
b=3 #Andra termen
c=a+b #Summan
print("Suman blir " + str(c))

Notera hur funktionen str(c) behövs för att omvandla ett tal till en sträng. Annars blir + obegripligt för Python.

Uppgift 1.1
Gör om programmet i övning 3 så att du istället kan skriva in två tal som programmet summerar. Tips: använd funktionen input() och float(). Spara som Upp1.py innan du kör.

Överkurs: Ovanstående program kan alla minskas med en rad. Hur?

Överkurs: Läs om snygga sätt att använda print() här.

Matematikmodulen

 Just nu kan du endast utföra enklare beräkningar. För att kunna använda roten ur, sinus, cosinus mm. måste du importera Pythons matematikmodul till ditt program.
Detta görs genom att först i programmet skriva import math.
När du sedan använder funktionerna skrivs de som math.xxx() där xxx() är den funktion du vill använda. Exempelvis math.sin(v) beräknar sinus för vinkeln v.

Övning 1.5
Skriv nedanstående program för att testa att använda matematikmodulen. Spara som Ovn5.py. Notera att alla vinklar är i radianer.

import math

vinkeln=float(input("vinkeln="))
sv=math.sin(vinkeln)
print("sin(" + str(vinkeln) + ")=" + str(sv)) #En snygg utskrift av svaret


Kontrollera att allt fungerar med några beräkningar.

Inlämningsuppgift 1.1
Skriv ett program som löser x2+px+q=0 med hjälp av pq-formeln. Kommentera viktiga beräkningar.
Tips: Roten ur x skrivs  math.sqrt(x) och x2 skrivs enklast x*x. Spara som Inl1.py

Överkurs: Skriv om programmet så att det löser den allmänna andragradsekvationen ax2+bx+c=0.

Introduktion

Bloggen innehåller kursmaterial för kursen programmering 1.

Angående övningar, uppgifter och inlämningsuppgifter

  • Övningar behöver inte redovisas. Men säkerställ att du gjort rätt och fråga vid behov.
  • Uppgifter redovisas för mig muntligt under lektionen om inte annat överenskommits.
  • Inlämningsuppgifter ska redovisas genom inskickande av programmet eller referens till dess plats på servern. Se till att det tydligt framgår vem du är och vilken uppgift det rör sig om.

Överkurs: Är fördjupningar som du gör om du har tid och möjlighet.