Podczas instalacji Centos na Windows 10 z HyperV pojawil się komunikat:
The image’s hash and certificate are not allowed (DB)
Plik z instalają był pobrany z pewnego źródła, więc komunikat był trochę zastanawiający….
Przyczyną była opcja „Enable Secure Boot”, która jest domyślnie zaznaczona na nowej maszynie wirtualnej. Żeby ją wyłaczyć należy wejść w ustawienia maszyny wirtualnej, w sekcji Security odszukać zaznaczonej opcji „Enable Secure Boot”, odznaczyć ją, zapisać zmiany i gotowe!
Zaczynamy od zainstalowania pakietu pixiedust. W tym celu w anaconda prompt wykonaj polecenie:
pip install pixiedust
Teraz już w Jupyter Notebook należy załadować moduł odpowiedzialny za debugowanie:
import pixiedust
Kiedy chcesz rozpocząć debugowanie kodu dodaj do niego linijkę %%pixie_debugger, o tak:
%%pixie_debugger
i = 1
while i < 10:
print(i)
i += 3
if i % 2 == 0:
i -= 2
print('done i={}'.format(i))
Po uruchomieniu tej komórki, zostanie pod nią wyświetlony interfejs debuggera:
Nie wchodząc zbytnio w szczegóły pierwszy pomarańczowy przycisk uruchamia kod dalej (run), drugi - ze strzałką wykonuje jedną linijkę kodu itd. Warto po prostu poczytać dymki widoczne w tych raptem kilku widocznych poleceniach.
Kiedy chesz sprawdzić wartość wyrażenia korzystasz z evaluate:
A kiedy chcesz zatrzymać program w określonej linijce, kliknij na numerze tej linijki myszką. W ten sposób zdefiniujesz breakpoint symbolizowany ikonką rozdeptanego robaka na marginesie. Numer linii będzie można też zobaczyć w okienku Breakpoints.
I co? Nie da się? Da się, tylko może jest potrzebnych kilka dodatkowych kroków!
W Pythonie występuje funkcja globals(), która zwraca tablicę przechowującą wszystkie zmienne sesji. Kiedy chcesz utworzyć nową zmienną, możesz po prostu dodać nowy element do tej listy
for i in range(0, 3):
globals()['var_{}'.format(i)] = i * 100
print(var_0, var_1, var_2)
Tutaj przechodzimy pętlą for przez kod 3 razy i tworzymy zmienne o nazwach var_0, var_1 i var_2. Żeby się przekonać, że instrukcja wykorzystująca funkcję globals działa, wyświetlamy zmienne podając ich statyczne nazwy, jakie na tym etapie wykonania kodu powinny już istnieć.
Zależnie od wykorzystywanego edytora, przy linijce zawierającej ten kod może się pojawić ostrzeżenie:
Skoro ta metoda jest taka zła, to czego używać zamiast tego? Można by próbować z listą:
my_list = []
for i in range(0, 3):
my_list.append(i * 100)
print(my_list[0], my_list[1], my_list[2])
W tym przypadku chodziło o instalację Centosa, który został zaintalowany w środowisku graficznym. Z grafiką jednak pojawiły się problemy powodujące, że serwer całkowicie się blokował (problemy z klawiaturą).
Oto jak uruchomić Linuxa bez grafiki, ale z obsługą sieci (run level 2 lub 3): Czytaj dalej »
Kiedy robisz rzeczy standardowe, korzystasz sobie ze standardowych metod, ale kiedy przychodzi zmierzyć się z niestandardowym problemem, to trzeba sięgnąć po funkcję apply.
Tutaj mamy dosyć nietypowy DataFrame. Dla każdego wiersza DataFrame trzeba wykonać jakąś niestandardową czynność…
Dajmy na to, że w zależności od zawartości kolumny „rola” trzeba zwrócić taki albo inny DataFrame – ogólnie wykonać jakąś złożoną operację. W tym celu zdefiunujemy funkcję. Pisząc ją myśl, jakby miała pracować na wierszu z DataFrame. Do dyspozycji masz zmienną row, możesz się odwoływać do niej, jak do wiersza danych, sprawdzać wartości, pobierać dane, budować if, while – cokolwiek. Funkcja ta może zwracać nowy obiekt Series:
Odpowiadając krótko – wtedy kiedy chcesz mieć pewność że jakieś instrukcje wykonają się NA PEWNO i ZAWSZE. Nawet w bardzo dziwnych i nietypowych sytuacjach.
Zazwyczaj np. uważamy, że kod w funkcji po słowie return się nie wykona:
def DoSomething(a,b):
c=a+b
return c
c=3+3
return c
DoSomething(1,1)
i rzeczywiście tak jest:
Out[66]: 2
Ale kiedy popatrzysz na taki zwariowany kod:
def TestTryCatchFinally(a,b):
try:
print('starting TRY')
c = a / b
print('ending TRY')
return c
except:
print('starting EXCEPT')
c = b / a
print('ending EXCEPT')
return -1
finally:
print('starting FINALLY')
c = 9
return c
print('ending FINALLY')
Programista bez debuggera, to jak mechanik bez klucza… to trzeba mieć!
Ostatnio bardzo popularnym narzędziem do tworzenia skryptów w Pythonie jest Jupyter Notebook. Niestety domyślnie menu nie ma polecenia debug… o ile w pojedynczych komórkach po prostu wykonujesz mało skomplikowane polecenia, to ewentualne dodanie polecenia print powinno pomóc i rozwiązać problem. Co jednak zrobić jeżeli masz nieco bardziej złożoną pętlę i coś w niej nie działa?
W charakterze kłopotliwego kodu wystąpi u nas taka pętla:
i = 1
while i < 10:
print(i)
i += 3
if i % 2 == 0:
i -= 2
print('done i={}'.format(i))
W sumie - nic skomplikowanego, ale zmienna sterująca i jest raz zwiększana, raz zmiejszana... idzie się pogubić, zwłaszcza po drinku.
W celu debuggowania w trybie "znakowym" wykonaj takie czynności:
załaduj moduł pdb:
import pdb
a następnie w miejscu, gdzie chcesz aby zatrzymał się program dodaj linijkę:
pdb.set_trace()
Czyli nasza kłopotliwa pętelka może teraz wyglądać tak:
import pdb
i = 1
while i < 10:
print(i)
i += 3
if i % 2 == 0:
pdb.set_trace()
i -= 2
print('done i={}'.format(i))
Po uruchomieniu w/w kodu, kiedy wykonanie dotrze do linijki
pdb.set_trace()
program zatrzyma się prezentując proste pole do wprowadzenia instrukcji:
jeśli wpiszesz "i" i naciśniesz enter, to debugger wyświetli w odpowiedzi aktualną wartość i. W okienku możesz też podawać bardziej skomplikowane wyrażenia, np sprawdzać ile wynosi i % 2 lub czy i %2 == True itp.
Kiedy chcesz aby zostało wykonane kolejne polecenie wystarczy nacisnąć n i enter. A kiedy masz już dosyć przetwarzania linijka po linijce naciśnij c i enter
Można też wpisać help, na co debugger odpowie listą dostępnych poleceń, lub wpisać help <nazwa_komendy> i wtedy zobaczysz opis polecenia:
Nasza sesja debuggowania mogłaby więc koniec końców wyglądać tak: