Moduł wdi (w archiwum wdi.tgz)
slajdy tu
@ MIM UW
Dzisiejszym zadaniem jest stworzenie pakietu testującego szybkość napisanych przez nas funkcji sortujących. Do zadań pakietu należeć będzie wczytywanie list – instancji problemów zapisanych w kilku różnych formatach, a następnie opracowanie porównania szybkości działania różnych funkcji sortujących na wczytanych listach. Dodatkowo chcemy mieć funkcję generate_list(file_name, swaps_no, length), która zapisze do pliku o ścieżce file_name listę liczb naturalnych od 1 do length wg algorytmu o następującym pseudokodzie:
a ← range(length) for i from swaps_no to 1 do di ← random element of { 0, ..., (length - swaps_no + i - 2) } swap a[di] and a[length - swaps_no + i - 1] return a
Szczegóły implementacji:
Pakiet ma się składać z trzech modułów. Pierwszy z nich będzie zawierał funkcje sortujące (ważne, żeby były to funkcje o takim samym interfejsie, czyli przyjmujące jako jedyny parametr listę, a zwracające listę posortowaną). Drugi moduł będzie zawierał funkcje wczytujące listy z plików w następujących formatach:
li1:
[4, 3, 1, 2, 4, 5]
li2:
4
3
1
2
4
5
li3:
4 3 1 2 4 5
W drugim module powinny się znaleźć trzy funkcje, które przyjmują jako parametr nazwę pliku, a zwracają wczytaną z tego pliku listę.
Trzeci moduł ma przeszukiwać bieżący katalog w poszukiwaniu instancji problemów (plików o rozszerzeniach li1, li2 lub li3) i dla każdego z takich plików ma wywoływać wszystkie dostępne w pierwszym module funkcje testujące wraz z informacją na temat czasu działania każdego z nich na poszczególnych instancjach problemu. Dodatkowo ma zawierać funkcję generate_list.
Trzeci moduł powinien dawać się wywoływać z linii poleceń za pomocą polecenia: python compare_sorts.py [opcje]. Powinien udostępniać przynajmniej opcje:
-h – pomoc na temat sposobu wywołania skryptu
-g len – generowanie zestawu 9 plików testowych, zawierających listy o długości len, po trzy w każdym formacie. Dla każdego formatu pliki powinny zostać wygenerowane funkcją generate_list z parametrami swaps_no równymi odpowiednio 10, (len / 3) i len – 1.
Dzis zamiat slajdow do wykladu plik z kodem i komentarzami:
#WDI Wykład 6
#O zmiennych,
#czyli 100 sposobów strzelenia sobie w stopę
#Bartek Wilczyński
#zmienne lokalne w funkcjach
#Funkcje mogą używać zmiennych lokalnych
y=3
def f():
#tu juz nie widze zmiennej globalnej y
y=5
return y
#mogą też używać zmiennych globalnych
def g():
#tu widze zmienna y
return y
#ale nie mozemy mieszac tych dwoch stylow!
#to bedzie dzialac
def py():
print y
#a to juz nie!
def ppy():
print y
y=1
#Dlaczego? Dlatego, że zmienna y byłaby globalna w 1 linii i lokalna w 2giej
#Czasem chciałbym _zapisać_ coś na zmiennej globalnej
#mogę wtedy użyć deklaracji "global"
#np. tak:
count=0
def add_count():
global count
count+=1
return count
#to oczywiscie bez global nie zadziala...
def add_count():
#global count
count+=1
return count
#A jakie sa argumenty funkcji: globalne, czy lokalne?
y=1
def f(x):
x+=1
return x
print f(y)
y
#jak widac - lokalne,
#tzn nie nie mozemy nadpisac zmiennej globalnej, przekazanej przez parametr
#Ale, czy tak jest zawsze?
def f(x):
x+=x
#jesli uzyje f(liczba), to dobrze
y=1
f(y)
y
#ale dla list dzieje sie cos dziwnego...
l=[1,2]
f(l)
l
#co ciekawe, lekka zmiana funkcji f:
def f(x):
x=x+x
#naprawia dzialanie dla list
l=[1,2]
f(l)
l
# i nie psuje dla liczb:
y=1
f(y)
y
# O co tu chodzi????
#Podobny mechanizm bedzie dzialal dla list i slownikow przy wstawianiu
def f(x):
x[0]=1
#
l=[1]
f(l)
l
d={}
f(d)
d
#Otóż chodzi o to, że python "ulokalnia" zmienne tylko wtedy
#gdy używamy instrukcji przypisania np x=x+x
# a nie wtedy gdy "uzywamy" zmiennej:
#np x[0]=1 czy nawet x+=x
#Ale dlaczego f(x) dzialalo dla liczb? def f(x):
def f(x):
x+=x
print x
#jesli uzyje f(liczba), to dobrze
y=1
f(y)
y
#???
I jeszcze dla napisów też:
s="ala"
f(s)
s
#???????
#Otóż to się wiąże z różnymi rodzajami zmiennych:
# modyfikowalne (mutable) - takie jak listy i słowniki
# niemodyfikowalne (immutable) - takie jak liczby i napisy
#zmienne modyfikowalne będą "pozwalały" zmieniać swoją wartość
#a niemodyfikowalne - nie
#to się wiąże z pojęciem referencji, czyli "odnosnika" do wartosci
#w pythonie (jak w wiekszosci jezykow dynamicznych) miedzy wartosciami (miejsca w pamięci)
#a zmiennymi sa referencje
#zwykle podczas przypisania zmieniamy tylko referencje:
l=[1,2,3]
l2=l
l2+=[1]
l
# zmienna l2 jest tylko "referencja" do zmiennej l
# to samo dzieje sie w przypadku przekazywania parametrow
#python uzywa przekazywania "przez referencje"
#ale zmienne niemodyfikowalne sa bardziej skomplikowane:
s="ala"
s2=s
s2+="ala"
#tutaj w momencie przypisania dokonywane jest "odwiazanie" (dereferencja)...
print s
print s2
#Mozemy sprawdzac "rownosc" referencji przy pomocy funkcji id() i konstrukcji "is"
l=[1]
l2=l #ta sama lista
l3=[1] # inna lista...?
id(l)
id(l2)
id(l3)
l==l2 #?
l==l3 #?
l is l2 #?
l is l3 #?
#To oczywiscie dziala inaczej dla wartosci niemodyfikowalnych
s="ala"
s2=s # ten sam napis
s3="ala" # inny napis?
s is s3 #?
#Trzeba tez bardzo uważać zinicjowaniem list...
ll= [[]] *5
print ll
ll[0].append(0)
print ll[0] # ok
print ll #oops!
#ale tez z parametrami domyslnymi
def f(l=[]):
l.append(1)
return l
print f() #ok...
print f() # ???
#No to jak "rozplesc" dwie listy?
l=[1,2,3]
l2=l
l3=l[:]
l2.append(2)
l3.append(3)
print l2
print l3
print l #?
#ze slownikami jest podobnie, do kopiowania sluzy metoda .copy()
d={}
d2=d
d3=d.copy()
d[1]=[]
print d,d2,d3
d[1].append(1)
print d
#ale kopiowanie jest "plytkie"...
d4=d.copy()
print d4
d[1].append(2)
print d4
## Juz wartosci pod kluczami pozostaja "wspolne"....
#Mamy na szczescie modul copy
import copy
#ktory umie robic kopie "glebokie":
d5=copy.deepcopy(d)
print d,d5
d[1].append(4)
print d,d4,d5
#Sprobujmy sobie jeszcze skomplikowac zycie,
#I zdefiniujmy funkcje wewnatrz funkcji:
y=1
def f(x):
y=5
def g(x):
y=x+6
return y
print y
return y+g(x)
f(y) #?
y #?
y=1
def f(x):
y=5
def g(x):
global y # mala zmiana?
y=x+6
return y
print y #tego y'ka nie ruszylismy...
return y+g(x)
f(y)
y
# A co sie stanie jesli zmienimy wartosc zmiennej po deklaracji funkcji...
x=1
def f():
return x
f()
x=2
f()
#Chyba, ze uzyjemy "domkniecia":
def pomnoz_przez(x):
def f(y):
return x*y
return f
x=5
przez_5=pomnoz_przez(x)
przez_5(10)
x=20
przez_5(20)
#
#
slajdy tu
Słowniki:
Zbiory:
Plik dmel-4-r5.47.gff zawiera anotacje chromosomu 4 muszki owocowej. Każda linijka stanowi pojedynczy wpis – rekord, składający się z kilku pól, m.in. nazwy chromosomu (kolumna 0), typu rekordu i spełnianej w ramach tego typu roli (kolumny 1 i 2), początkowej i końcowej pozycji wpisu (liczby całkowite, w tysiącach par zasad – kolumny 3 i 4), opcjonalnie wartości odczytu (tzw. score, kolumna 5), znaku nici DNA, której dotyczy wpis (+ lub -, kolumna 6) i deskryptora (kolumna 8).
Zadania w postaci kodu źródłowego (w jednym pliku zadanie1_nr-indeksu.py) i plików wynikowych (załączniki z rozszerzeniem .txt lub .gff, żadnych kompresji itp.) przesyłają Państwo do obu prowadzących ćwiczenia (bartek@mimuw.edu.pl i pawel.bednarz@mimuw.edu.pl) przed wykładem za dwa tygodnie (26. XI 2012, 12:15). Proszę o umieszczenie w tytule e-mail’a hasła [WDI-1] i o wysyłanie ze skrzynek studenckich (aby łatwiej było zidentyfikować autora i ew. “zapożyczenia”).
Slajdy z wykładu tu
Zadania na rekurencję:
**** *** ** *
o n liniach.
def f(n): if n % 2 == 0: return n / 2 else: return 3*n + 1
Napisz rekurencyjną funkcję collatz_steps(n), która zwróci dla zadanego n liczbę elementów ciągu n, f(n), f(f(n)), …, potrzebnych do osiągnięcia 1. Np.
collatz_steps(1) == 0 collatz_steps(4) == 2
Wskazówka 1: funkcję f można zdefiniować np. tak:
def f(x): import math return math.tan(x - math.pi)
i dalej wywołać funkcję bisect na funkcji f: bisect(f)
Wskazówka 2: zastosuj metodę “połowienia” przedziału <0;n> – podobnie jak to miało miejsce w przypadku wyszukiwania binarnego.
Zadania wg. P. Bednarza
def f(a, b): if b == 0: return 0 return a + f(a, b - 1)
def e(n): if n == 0: return True else: return o(n - 1) def o(n): if n == 0: return False else: return e(n - 1)
def take(l): if l == []: return [] else: return [l[0]] + skip(l[1:]) def skip(l): if l == []: return [] else: return take(l[1:])