EXA2. 1,5hp: Algoritmseminarier och algoritmrapporter
Betyg LAB2
Väntar på attestering av examinator
"Plussning" är ej möjligt på FilFak, dvs när ett betyg rapporterats in i Ladok går det inte att höja det genom komplettering → Deadlines för kompletteringar på kurshemsidan
# Vi kan inte använda någon funktion utan att "kedjan" körs
def a(arg):
# kod -> resultat
b(resultat)
def b(arg):
# kod -> resultat
c(resultat)
def c(arg):
# kod -> resultat
d(resultat)
def d(arg):
# kod -> resultat
return resultat
if __name__ == "__main__":
a()
# Vi kan använda a(), b(), c() och d() oberoende av varandra.
# OBS! MYCKET DÅLIGA funktions/variabelnamn i exempelet nedan
def a(arg):
# kod -> resultat
return result
def b(arg):
# kod -> resultat
return result
def c(arg):
# kod -> resultat
return result
def d(arg):
# kod -> resultat
return result
if __name__ == "__main__":
# kod -> value
result1 = a(data)
result2 = b(result1)
result3 = c(result2)
result4 = d(result3)
# Vi kan använda a(), b(), c() och d() oberoende av varandra.
# OBS! MYCKET DÅLIGA funktions/variabelnamn i exempelet nedan
def a(arg):
# kod -> resultat
return result
def b(arg):
# kod -> resultat
return result
def c(arg):
# kod -> resultat
return result
def d(arg):
# kod -> resultat
return result
if __name__ == "__main__":
# kod -> value
result = d(c(b(a(data))))
Markera kod för funktion, sök ersätt i funktionen
Funktionsnamn: verbliknande
I Python gäller att datatyper == klasser
Sike! Ni har använt objekt hela tiden!
list
¶list
som användas (som en mall) för listor (inbyggda klasser i Python börjar oftast med gemen).list
genom att anropa klassenlist
kan vi skicka med ett argument när vi skapar en instanslist()
→ instans av klassen list
som ännu inte innehåller några elementmy_variable = list()
list(range(3))
→ instans av klassen list
som innehåller talen 0, 1, 2my_other_variable = list(range(3))
my_variable.reverse()
my_variable.sort()
list
¶print(list)
<class 'list'>
list
¶list()
[]
list
¶my_variable = list()
print(my_variable)
[]
list
¶print(type(my_variable))
<class 'list'>
list
¶print(len(my_variable))
0
list
¶print(my_variable.append(1))
None
list
¶print(my_variable)
[1]
Dog
som är tänkt att användas (som en mall) för representationer av hundar.Dog
Dog("Pluto")
→ instans av klassen Dog
som används för att representera en hund med namnet Plutodog1 = Dog("Pluto")
Dog("Fido")
→ instans av klassen Dog
som används för att representera en hund med namnet Fidodog2 = Dog("Fido")
dog1.name
dog1.speak()
class Dog(object):
def __init__(self, namev):
self.name = namev
self.age = 0
def speak(self):
print("Voff, jag heter " + self.name)
def set_name(self, new_name):
self.name = new_name
dog1 = Dog("Fido")
dog1.set_name("Pluto")
dog2 = Dog("Lassie")
dog1.speak()
dog2.speak()
print(dog1.name)
Voff, jag heter Pluto Voff, jag heter Lassie Pluto
class
används för att definiera en ny klass, på ungefär sätt som def
används för att definiera en funktion.class
följs av namnet på den klass man skapar samt vilken eller vilka basklasser vår nya klass bygger på.object
.class Dog(object):
def
på samma sätt som vilken funktion som helst, med ett undantag.self
för den första parametern.self
för att komma åt instansvariabler eller andra metoder.def speak(self):
print("Voff, jag heter " + self.name)
Klassnamn(arg1, arg2, ..., argn)
__init__()
-metod__init__()
och lagras i parametern som vi kallar self
.__init__()
efter self
.def __init__(self, namev):
self.name = namev
self.age = 0
hund1.age = 4
hund2.age = 8
def set_age(self, new_age):
if self._age_change_allowed(new_age):
self.age = new_age
_age_change_allowed
.def increment_age(self):
if self._age_change_allowed():
self.age += 1
increment_age
inte tar några andra argument än self
) utan informerar bara objektet om att det är dags att öka åldern med ett år.För klassen Dog
class Dog(object):
def __init__(self, namev):
self.name = namev
self.age = 0
def speak(self):
print("Voff, jag heter " + self.name)
def set_name(self, new_name):
self.name = new_name
För funktioner utan returvärde (dvs som alltid returnerar None
i Python) utelämnas ofta returvärde i klassdiagram.
class Dog(object):
def __init__(self, namev):
self.name = namev
self.age = 0
def speak(self):
print("Voff, jag heter " + self.name)
def set_name(self, new_name):
self.name = new_name
För klassen Book
class Book:
def __init__(self, title):
self.title = title
self.author = "Unknown"
self.year = None
def print_citation(self):
if not self.year:
year = "N/A"
else:
year = self.year
print(f"{self.author}. ({year}). {self.title}.")
En härledd klass har alla egenskaper och beteenden som dess basklass har, men kan utöka dessa.
Analogt exempel från biologin: taxonomi
Student
och Teacher
Person
för att hantera dettaa_list = []
syntaktiskt socker för a_list = list()
a_dict = {}
syntaktiskt socker för a_dict = dict()
dog3 = Dog("Lassie")
objekt.variabel
objekt.metod()
a = [1, 2, 3]
a.append(4)
s = "hejsan"
s.upper()
class Person(object):
def __init__(self, name, pid):
self._name = name
self._pid = pid
class Student(Person):
def get_email(self):
return self._pid + "@student.liu.se"
class Teacher(Person):
def get_email(self):
return self._name.replace(' ', '.').lower() + "@liu.se"
dude1 = Teacher("Johan Falkenjack", "johsj47")
dude2 = Student("Johan Sjöholm", "johsj304")
dude1.get_email()
'johan.falkenjack@liu.se'
dude2.get_email()
'johsj304@student.liu.se'
obj1
) som får en referens till den klass den tillhör samt vilken klass som är dess basklass.__init__
är definierad i obj1
s klass, anropas den metoden med en referens till obj1
.__init__
inte är definierad i obj1
s klass, letar Python vidare i obj1
s basklass.__init__
inte är definierad i obj1
s basklass, letar Python vidare i obj1
s basklass basklass__init__
varpå den metoden körs med en referens till obj1
object
¶Student
är en Person
Teacher
är en Person
DepartmentHead
är en Professor
som är en Teacher
som är en Person
osv.object
.# definition av klassen Dog med explicit basklass; object
class Dog(object):
pass
# också godkänd definition av klassen Dog, ingen basklass angiven;
# basklassen object antas implicit av Python
class Dog:
pass
# ingen explicit basklass; Python antar att object är basklass
class GameCharacter:
pass
# explicit basklass - GameCharacter
class PlayerCharacter(GameCharacter):
pass
# explicit basklass - GameCharacter
class EnemyCharacter(GameCharacter):
pass
class NamedList(list):
def setName(self, name):
self._name = name
def getName(self):
return self._name
nlist = NamedList()
print(nlist)
nlist.append(12)
nlist.setName("The best list")
print(nlist.getName())
print(nlist)
[] The best list [12]
__
¶__str__()
__init__()
används när en instans av en klass skapas__str__()
används när en instans av en klass (ett objekt) ska visas som en sträng. Ska returnera en sträng.__add__()
används om man vill att +
-operatorn ska fungera för objekt av den aktuella klassenclass Book:
def __init__(self, title):
self.title = title
self.author = "Unknown"
self.year = None
def __str__(self):
if not self.year:
year = "N/A"
else:
year = self.year
return f"{self.author}. ({year}). {self.title}."
bok1 = Book("Python från början")
bok1.author = "Jan Skansholm"
# OBS! Vi anropar inte metoden __str__ själva utan print-funktionen anropar den automatiskt
print(bok1)
Jan Skansholm. (N/A). Python från början.
a = ["hej"]
b = a
a.append("hopp")
b.append("ojdå")
print(a)
→ ["hej", "hopp", "ojdå"]
print(b)
→ ["hej", "hopp", "ojdå"]
book1 = Book("Titel1")
book2 = book1
book1.title = "Python från början"
print(book2.title)
Python från början
Formulera problemet: Gör problemet väldefinierat: För vilka input vill vi kunna komma fram till en lösning? Vilka är normalfallen? Finns extremfall?
Output: Hur ser en lösning ut? Vad är en korrekt lösning? Finns flera korrekta lösningar? Finns det en bästa lösning?
for
-loop, leta efter största elementetdef get_max_value(values):
max_value = values[0]
for value in values:
if value > max_value:
max_value = value
return max_value
len(values)
;def get_max_value(values):
max_value = values[0]
for value in values:
# Ju större len(values) är, desto mindre betydelse
# har antalet operationer i for-loopen.
if value > max_value:
max_value = value
return max_value
def get_max_value(values):
max_value = values[0]
number_of_operations = 0
for value in values:
number_of_operations +=1
if value > max_value:
max_value = value
print(f"{number_of_operations=}")
return max_value
from random import sample
random_values = sample(range(1000), k=100)
print(f"{random_values=}")
print(get_max_value(random_values))
random_values=[508, 848, 559, 574, 916, 764, 774, 504, 519, 527, 946, 746, 239, 39, 35, 38, 945, 727, 130, 210, 683, 398, 0, 718, 314, 475, 145, 989, 404, 77, 452, 862, 447, 923, 576, 56, 699, 717, 425, 492, 921, 6, 529, 90, 196, 585, 655, 998, 706, 121, 88, 979, 650, 12, 138, 167, 674, 677, 78, 134, 157, 778, 136, 418, 186, 146, 827, 951, 42, 320, 30, 853, 215, 843, 871, 224, 128, 259, 366, 911, 709, 912, 3, 373, 409, 308, 503, 523, 794, 99, 369, 564, 775, 32, 993, 484, 924, 13, 502, 593] number_of_operations=100 998
[1, 2, 3, ..., n ]
def get_pairs(values):
pairs = []
for v1 in values:
for v2 in values:
pairs.append(str(v1) + ":" + str(v2))
return pairs
def get_pairs(values):
pairs = []
number_of_operations = 0
for v1 in values:
for v2 in values:
number_of_operations += 1
pairs.append(str(v1) + ":" + str(v2))
print(f"{number_of_operations=}")
return pairs
values = range(7)
print(f"{values=}")
print(get_pairs(values))
values=range(0, 7) number_of_operations=49 ['0:0', '0:1', '0:2', '0:3', '0:4', '0:5', '0:6', '1:0', '1:1', '1:2', '1:3', '1:4', '1:5', '1:6', '2:0', '2:1', '2:2', '2:3', '2:4', '2:5', '2:6', '3:0', '3:1', '3:2', '3:3', '3:4', '3:5', '3:6', '4:0', '4:1', '4:2', '4:3', '4:4', '4:5', '4:6', '5:0', '5:1', '5:2', '5:3', '5:4', '5:5', '5:6', '6:0', '6:1', '6:2', '6:3', '6:4', '6:5', '6:6']
pycodestyle
som används för att kontrollera PEP 8 och paketet pydocstyle
som används för att kontrollera PEP 257pycodestyle
och pydocstyle
finns installerade i en virtuell miljö som hittas i /courses/729G46/venv_pep
source /courses/729G46/venv_pep/bin/activate
pycodestyle <fil> ...
samt pydocstyle <fil> ...
"""
)class Klassnamn(Basklassnamn):
def funktionsnamn():
och def metodnamn():
"""Return all odd numbers in the argument value_list."""
"""The function returns all odd numbers in the argument value_list"""
"""
och skrivs som första rad efter bl.a. klass-/funktions-/metod-huvud#
och som skrivs ovanför det block som de tillhör#
och skrivs bredvid koden som de gällerpycodestyle
för att kontrollera PEP8pydocstyle
för att kontroller PEP257Tillägg för "linting" i Visual Studio Code
Mer information på kurshemsidan
Vad borde funktionen/metoden returnera? Gör den det?
Interaktivt läge: ipython3 -i <filnamn>
ls
, cd
, cat
, etc. fungerar%run <filnamn>
- kör fil%reset
- rensa minnet från användarens variablerif __name__ == "__main__":
# testkod här
def main():
for filename in sys.argv[1:]:
open_file = open(filename)
data = []
for line in open_file:
# en rad blir en lista där varje komma-separerat
# värde blir ett element
data.append(line.rstrip().split(","))
open_file.close()
# alla sanna positiva
tp_rows = []
for row in data:
if row[3] == "[n]" and row[4] == "[n]":
fp_rows.append(row)
# alla sanna negativa
tn_rows = []
for row in data:
if row[3] == "[b]" and row[4] == "[b]":
tn_rows.append(row)
# alla falska positiva
fp_rows = []
for row in data:
if row[3] == "[b]" and row[4] == "[n]":
fp_rows.append(row)
# alla falska negativa
fn_rows = []
for row in data:
if row[3] == "[n]" and row[4] == "[b]":
fn_rows.append(row)
def load_data(filename):
open_file = open(filename)
data = []
for line in open_file:
data.append(line.rstrip().split(","))
open_file.close()
return data
def main():
for filename in sys.argv[1:]:
data = load_data(filename)
# alla sanna positiva
tp_rows = []
for row in data:
if row[3] == "[n]" and row[4] == "[n]":
fp_rows.append(row)
# alla sanna negativa
tn_rows = []
for row in data:
if row[3] == "[b]" and row[4] == "[b]":
tn_rows.append(row)
# alla falska positiva
fp_rows = []
for row in data:
if row[3] == "[b]" and row[4] == "[n]":
fp_rows.append(row)
# alla falska negativa
fn_rows = []
for row in data:
if row[3] == "[n]" and row[4] == "[b]":
fn_rows.append(row)
def load_data(filename):
open_file = open(filename)
data = []
for line in open_file:
data.append(line.rstrip().split(","))
open_file.close()
return data
def filter_values(index1, index2, value1, value2, value_list):
filtered = []
for value in value_list:
if value_list[index1] == value1 and value_list[index2] == value2:
filtered.append(value)
return filtered
def main():
for filename in sys.argv[1:]:
data = load_data(filename)
# alla sanna positiva
tp_rows = filter_values(3, 4, "[n]", "[n]", data)
# alla sanna negativa
tn_rows = filter_values(3, 4, "[b]", "[b]", data)
# alla falska positiva
fp_rows = filter_values(3, 4, "[b]", "[n]", data)
# alla falska negativa
fn_rows = filter_values(3, 4, "[n]", "[b]", data)
def main():
for filename in sys.argv[1:]:
open_file = open(filename)
data = []
for line in open_file:
# en rad blir en lista där varje komma-separerat
# värde blir ett element
data.append(line.rstrip().split(","))
open_file.close()
tp_rows = []
tn_rows = []
fp_rows = []
fn_rows = []
for row in data:
if row[3] == "[n]" and row[4] == "[n]":
fp_rows.append(row)
elif row[3] == "[b]" and row[4] == "[b]":
tn_rows.append(row)
elif row[3] == "[b]" and row[4] == "[n]":
fp_rows.append(row)
elif row[3] == "[n]" and row[4] == "[b]":
fn_rows.append(row)
def categorize_data(data):
catagorized = {"tp": [], "tn": [], "fp": [], "fn": [] }
for row in data:
if row[3] == "[n]" and row[4] == "[n]":
categorized["tp"].append(row)
elif row[3] == "[b]" and row[4] == "[b]":
categorized["tn"].append(row)
elif row[3] == "[b]" and row[4] == "[n]":
categorized["fp"].append(row)
elif row[3] == "[n]" and row[4] == "[b]":
categorized["fn"].append(row)
return categorized
def load_data(filename):
open_file = open(filename)
data = []
for line in open_file:
# en rad blir en lista där varje komma-separerat
# värde blir ett element
data.append(line.rstrip().split(","))
open_file.close()
return data
def main():
for filename in sys.argv[1:]:
data = load_data(filename)
categorized_data = categorize_data(data)