Styl, konwencje, zaliczenie
WPROWADZENIE
Zaliczenie kursu polega na zaliczeniu wykładu i laboratorium.
Obecność na wykładzie nie jest obowiązkowa, ale bardzo polecana.
Zaliczenie wykładu polega na zaliczeniu projektu programistycznego.
Zaliczenie laboratorium bazuje na aktywności na zajęciach oraz
na terminowym przesyłaniu rozwiązań zadań załączonych do każdej części kursu.
Należy przesłać rozwiązania zadań z minimum dziesięciu części kursu.
Warto stworzyć osobne repozytorium zdalne na potrzeby kursu (GitHub, Bitbucket, GitLab).
Możliwe sposoby przesyłania rozwiązań zestawów zadań i projektu:
(1) email z linkiem do repozytorium zdalnego,
gdzie składowane są kody źródłowe programów [zalecane],
(2) email z linkiem do archiwum ZIP w chmurze UJ,
(3) email z archiwum ZIP w załączniku.
Proszę nie przesyłać w załącznikach pojedynczych plików z rozszerzeniem .py,
ponieważ program pocztowy UJ nie pozwala ich otworzyć ani zapisać na dysku.
ZALECENIA DLA PRZESYŁANYCH ZADAŃ I PROJEKTU PROGRAMISTYCZNEGO
- Oficjalne zalecenia dotyczące stylu programowania (coding style)
w języku Python opisane są w PEP 8.
- Projekt programistyczny składa się z programu napisanego
w języku Python (minimum 100 linii kodu łącznie z komentarzami),
oraz dokumentacji programu.
- Program powinien prawidłowo działać na Studenckiej Pracowni
Komputerowej pod systemem Linux.
Zalecana forma programu to moduł, który może być importowany.
Może to być również samodzielny program, dostosowany do konwencji
znanych w systemie Linux, np. składnia NAZWA [OPCJA] [PLIK];
obsługa opcji wiersza poleceń -h, --help, -v, --version;
rozsądne zachowanie domyślne.
Zalecana tematyka projektu to implementacja wybranego algorytmu
nienumerycznego, który nie jest omawiany podczas kursu.
- Preferowane są programy działające w trybie tekstowym.
Wyjątkowo można wprowadzić elementy grafiki na bazie pygame
lub semigrafikę z ncurses.
- Kod programu powinien być czytelny na ekranie terminala 80x25,
czyli długość wierszy nie powinna przekraczać 80 znaków.
- Ze względu na częste problemy z kodowaniem polskich znaków
nie używać polskich liter w kodzie programu.
- Każdą instrukcję umieszczamy w osobnym wierszu.
- Funkcje muszą być krótkie (maksimum dwa ekrany)
i robić dobrze jedną rzecz.
Liczba zmiennych lokalnych w funkcji nie powinna przekraczać
5-10 (optymalnie do 7).
Używamy zmiennych globalnych wyłącznie tam, gdzie to konieczne.
- Wstawiać komentarze, które mają tłumaczyć CO robi program,
a nie JAK to robi.
Komentarz do funkcji lub klasy ma być na początku (docstring),
a raczej nie w kilku miejscach wewnątrz ciała funkcji.
Wyjątkiem mogą być sprytne triki.
- Programom zawsze powinny towarzyszyć testy poprawności.
Jest to szczególnie istotne dla języka interpretowanego,
jakim jest Python.
Zaleca się umieszczać testy w bloku instrukcji warunkowej
if __name__ == "__main__":
# testy
W najprostszym przypadku testy to wywołania funkcji dla pewnych
konkretnych danych.
Zaawansowany sposób to zastosowanie
modułu unittest lub doctest.
W trakcie tworzenia programu warto wstawiać pomocnicze instrukcje
print() do wyświetlania komunikatów np. z chwilowymi
wartościami zmiennych z programu.
Warto też użyć instrukcji assert do sprawdzania pewnych warunków
w różnych miejscach kodu.
- Kolejne działające wersje programu warto umieszczać w osobnych
katalogach (wersja1, wersja2, itd.) lub tylko w osobnych plikach
(program1.py, program2.py, itd.).
Zaawansowany i preferowany sposób pracy to korzystanie z wybranego systemu
kontroli wersji, np. git.
Pomocne jest zdalne archiwum git, które można założyć w jednym
z bezpłatnych serwisów (GitHub, Bitbucket, GitLab).
- Dokumentację programu piszemy w formatach otwartych
(HTML, LaTeX, PDF, Markdown), objętość kilka-kilkanaście stron.
Warto również w samym programie umieścić pomoc dla użytkownika.
Standardowe rozdziały dokumentacji to:
(1) wprowadzenie z opisem teoretycznym algorytmu,
(2) opis interfejsu,
(3) uwagi na temat implementacji, często
cytowany jest cały kod programu lub wybrane fragmenty,
(4) podsumowanie, wyniki testów, itp.,
(5) literatura wykorzystana przy tworzeniu projektu,
linki do stron w Internecie.
NAZWY ZMIENNYCH, FUNKCJI, KLAS
- Nie używać słów kluczowych jako nazw zmiennych.
Nie używać nazw typów wbudowanych jako nazw zmiennych (str, list).
- Nie używać małej litery l (jak Lucyna) jako nazwy zmiennej,
bo łatwo ją pomylić z 1 (jedynka).
- W nazwach zmiennych nie można używać polskich znaków,
dlatego lepiej wyglądają wyrazy angielskie, np.
my_variable (konwencja lower_case_with_underscores), my_function,
MyClass (konwencja CamelCase), my_module.
Czasem wystarczają krótkie nazwy, jak S (string), L (lista),
D (słownik), i, j, k (zmienne w pętlach).
- Nazwy rozpoczynające się od jednego znaku podkreślenia
(jak _X) nie są importowane za pomocą instrukcji
from module import *.
- Nazwy z dwoma początkowymi i końcowymi znakami podkreślenia
(jak __X__) są nazwami zdefiniowanymi przez system,
które mają specjalne znaczenie dla interpretera.
- Nazwy rozpoczynające się dwoma znakami podkreślenia
i niekończące się dwoma kolejnymi takimi znakami
(jak __X) są lokalne dla zawierających je klas.
- Nazwa self pełni w klasach specjalną rolę,
występuje jako pierwszy argument w metodach.
Również nazwa other przyjęła się w definicjach
metod opisujących działania na instancjach klas,
np. dodawanie, mnożenie.
Podobnie lepiej unikać korzystania z nazw obiektów wbudowanych.
INNE KONWENCJE
- Przy korzystaniu ze zdalnego archiwum należy zawsze w liście wstawiać
link do repo i informację o tym, który zestaw został ukończony.
- Przy przesyłaniu poprawionych rozwiązań zestawów odpowiadać
przez Reply (kontynuacja wątku), aby zachować historię komunikacji.
- Wcięcia w instrukcjach złożonych mają szerokość 4 spacji.
Warto pracować w edytorze, który nie wprowadza tabulacji do kodu.
- Używać pustych linii do rozdzielania funkcji i klas,
a także większych bloków kodu wewnątrz funkcji.
- Wstawiać spacje dokoła operatorów i po przecinkach,
ale nie bezpośrednio po nawiasach, np. a = f(1, 2) + 3.