tisdag 29 januari 2013

Klasser och objekt

Klassen Complex

Nedanstående visar ett exempel på klass och objekt skapade ur klassen. Klassen Complex fungerar som ett paket för komplexa tal.

import math

#Klassens definition
class Complex:
     #Konstruktor
     def __init__(self, realdel, imagdel):
         self.r = realdel
         self.i = imagdel

     def abs(self):
         return math.sqrt(self.r*self.r+self.i*self.i)
        
#Använder klassen
#Skapar objekt z av klassen Complex
z = Complex(3.0, -4.5)
print(str(z.r) + ", " + str(z.i))
print(z.abs())

Nya objekt skapas med konstruktorn __init__(self, realdel, imagdel). Varje nytt komplext tal skapas med värden på realdel och imaginärdel. Klassen innehåller även en metod abs() som returnerar absolutvärdet av det komplexa talet.

Övning 2.18
Lägg till en metod som returnerar det komplexa talet som en textsträng som vi normalt skriver komplexa tal. Ex: 3+4i och 2-5i. Kalla metoden string(self)
Testa din metod.

Övning 2.19
Lägg till en metod arg() som returnerar argumentet för det komplexa talet.
Tips: math.atan2(y,x) returnerar vinkeln, i radianer, från x-axeln korrekt runt hela varvet.
Testa din metod.

Standardvärden

Du kan lägga till standardvärden till konstruktorn för att möjliggöra en standardversion av ditt objekt. Det görs genom att skriva som exemplet nedan:

def __init__(self, realdel = 0, imagdel = 0):

 Nu ger z = Complex() det komplexa talet 0+0i och z = Complex(5) talet 5+0i.
Du kan dock inte enbart ange imaginärdelen då standardvärdena ersätts från vänster till höger för varje angivet argument.

Använda referens till objekt i metod och anonyma objekt

Följande metod lägger till det komplexa talet z till det ursprungliga objektet

     def add(self, z):
          self.r=self.r+z.r
          self.i=self.i+z.i

Övning 2.20
Lägg till metoden ovan till klassen Complex och testa genom att i huvudprogrammet till exempel skriva:

z.add(Complex(5,1))
print(z.string())

Ovanstående skapar ett anonymt objekt av klassen Complex med värdet 5+i och lägger till det till det ursprungliga objektet.

Övning 2.21
Skapa motsvarande metoder som ovanstående för subtraktion, multiplikation och division. (Kom ihåg att vid division förlänger du med konjugatet till nämnaren.)


måndag 14 januari 2013

Sökning och sortering


Sortering

Att sortera listor och andra uppsättningar data är viktigt inom många användningsområden och det finns ett stort antal algoritmer för detta.

Läs om sorteringsalgoritmer här.

Python har  en inbyggd metod för att sortera listor som är mycket effektiv:
lista.sort()

Sökning i listor

Om listan är oordnad är det enklast att söka från början till slut tills man hittar det man söker. Man behöver då i snitt söka genom hälften av listan innan man finner det sökta värdet.

Är listan sorterad kan sökningen snabbas upp betydligt genom en smart metod.

Binär sökning
I en sorterad lista kan man veta om man är före eller efter det sökta värdet. Man gör därför så att man gissar på det mittersta värdet inom det område man inte uteslutit. Se nedanstående bild som visar sökning efter talet 76:


Efter första gissningen vet man att talet är i den övre halvan.
Efter den andra vet man att talet är i den tredje fjärdedelen.
osv tills man finner det.

Uppgift 2.6
Skriv ett program som:
  •  Låter användaren mata in ett valfritt antal tal (Avsluta inmatningen med tex. att användaren skriver N). Talen läggs i en lista.
  •  Sorterar listan av tal.
  •  Med hjälp av binär sökning letar fram ett tal som användaren matat in. (Förutsatt att det finns i listan. Annars ett meddelande om att det inte finns.)

tisdag 8 januari 2013

Stackar och köer

Stack

I en stack placeras nya data överst i stacken och data hämtas också överst i stacken. Ordningen kallas ibland LIFO ("Last In Frist Out"). Stackar används ofta i matematiska rutiner och är fundamental för den interna funktionen i datorer.


I köer placeras nya data längst bak i kön och data hämtas från början av kön. Ordningen kallas ibland FIFO ("First In First Out"). Köer används då det är viktigt att bevara ordningen på datan.

Exempel som buffer

Följande övningar visar exempel på hur stack och kö fungerar som buffrar. En buffer lagrar temporärt data. De kan bland annat användas för att kunna processa data i jämn takt trots att den inkommande datan kommer in i mer ojämn takt vid internetuppkopplingar, bränning av skivor och mycket mer. Nedanstående exempel visar principen för en sådan buffer i form av en stack och en kö.

Övning 2.16

#Simulerar en stack där 0-2 nya element tillkommer varje sekund och ett
# poppas.

import random
import time

#Fyller stacken med 6 bokstäver. A underst i stacken
stack = ["A", "B", "C", "D", "E", "F"]
alfa = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
i = 6
while True :
    try : 
        print("Processar " + stack.pop())    
        print(stack)
    except IndexError :
        print("Stacken tom! Avslutar")
        break
    
    antal_nya = random.randint(0,2)
    while antal_nya > 0 :
        stack.append(alfa[i])
        i = (i + 1) % 26
        antal_nya = antal_nya - 1
    time.sleep(1)
    
print("Slut")


Övning 2.17

#Simulerar en kö (buffer) där 0-2 nya element tillkommer varje sekund och ett
# poppas.

import random
import time

#Fyller kön med 6 bokstäver. A först i kön
queue = ["A", "B", "C", "D", "E", "F"]
alfa = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
i = 6
while True :
    try : 
        print("Processar " + queue.pop(0))    
        print(queue)
    except IndexError :
        print("Buffern tom! Avslutar")
        break
    
    antal_nya = random.randint(0,2)
    while antal_nya > 0 :
        queue.append(alfa[i])
        i = (i + 1) % 26
        antal_nya = antal_nya - 1

    time.sleep(1)
    
print("Slut")