Funkcje i procedury

W dzisiejszym odcinku programowania dla nieprogramistów wytłumaczę Wam czym są funkcje i procedury w ujęciu programistycznym, bo nie są tym samym co np. w matematyce oraz pokażę oczywiście parę przykładów w kodzie 🙂

Zacznijmy tradycyjnie od krótkiej definicji, a później przełóżmy ją na bardziej przyjazny i zrozumiały język.

Co to jest funkcja lub procedura w informatyce?

Funkcja lub procedura to terminy ściśle związane z tzw. programowaniem proceduralnym (czym ono jest wyjaśnię może w osobnym odcinku o paradygmatach programowania)
Wg suchej definicji funkcja lub procedura to inaczej podprogram, czyli wydzielona część programu wykonująca zestaw instrukcji i realizująca dane zadanie, która jest możliwa do wykonania wielokrotnie podczas wykonywania programu. Podprogramy stosuje się, aby uprościć program główny i zwiększyć czytelność kodu.

Jeśli oglądaliście jeden z poprzednich filmów z tej serii od razu przyjdzie Wam na myśl pojęcie algorytmu. W uproszczeniu, można nawet powiedzieć, że procedura czy funkcja jest właśnie taką implementacją, zapisem danego algorytmu.
Jak widzicie informatyczna definicja funkcji jest zupełnie inna od tej znanej Wam z lekcji matematyki. Więc nie musicie się jej bać, nawet jeśli sinusy, cosinusy czy tangensy prześladują Was w nocnych koszmarach 😀

Czym jest funkcja w praktyce?

Suche definicje to jedno, ale moim zdaniem kluczem do zrozumienia istoty każdego zagadnienia jest umiejętność skojarzenia tego co już znamy z otaczającego Nas Świata z nowym pojęciem. Podobnie możemy zrobić i w tym przypadku.
Pamiętacie robienie herbaty z pierwszego odcinka? Trenowaliśmy w nim małego pomocnego robocika z przyszłości by przygotował Nam Nasz ulubiony ciepły napój i używając myślenia algorytmicznego, napisaliśmy w tym celu listę instrukcji, które Nasz mały asystent miał wykonać.
Jedna z osób zapytała pod filmem czy byłem sponsorowany przez producenta herbaty i o ile samo pytanie było dość zabawne, to poniekąd zwraca uwagę na pewien problem, ponieważ jeśli chcielibyśmy by Nasz robocik obsłużył gości na przyjęciu i przygotował kilka herbat i w dodatku o różnych smakach to mielibyśmy pewien problem. Oczywiście jeśli chodziłoby o przygotowanie kilku herbat, to wystarczyłoby uruchomić ręcznie program kilka razy, ale co jeśli chcemy przygotować jednej osobie herbatę marki X a drugiej herbatę marki Y? Czy musielibyśmy pisać od nowa cały program?

Otóż okazuje się, że nie i że ten problem jest dość uniwersalny w świecie informatycznym i programowania i dawno został rozwiązany przez właśnie stosowanie funkcji i procedur. Widzicie funkcja podobnie jak cały program przyjmuje na wejściu dane wejściowe, tzw. parametry funkcji. Możemy więc w Naszym „programie” prawie cały kod zapisać jako funkcja przygotowania napoju, a głównym kodzie programu przekazywać do tej funkcji parametr o nazwie smak.
Wtedy program wykonując się będzie uruchamiał cały ten blok kodu przekazując do niego zmienną z nazwą smaku, czy marki herbaty.
Dzięki temu kod programu będzie dużo bardziej czytelny, bo nawet jak zaprogramujemy zrobienie większej ilości różnych napojów to nadal będziemy w stanie odczytać w miarę szybko i sprawnie co Nasz program robi.
Oczywiście w przyszłości jak poznamy pętle i instrukcje warunkowe, będziemy mogli jeszcze go bardziej udoskonalić.

Jak wygląda procedura w kodzie?

Zacznijmy może na początek od procedury. Wszystkie przykłady będę pokazywał w Pythonie, ale na koniec pokażę też przykłady w innych językach.
Procedury czy funkcje należy zwykle zadeklarować. W Pythonie robimy to poprzez słowo kluczowe def, następnie podajemy nazwę funkcji, i tutaj podpowiem od razu, że zgodnie z obowiązującym standardem PEP8 dla tego języka nazwa funkcji lub procedury powinna być pisana z małej litery, a jeśli składa się z więcej niż jednego słowa to powinna być rozdzielona znakiem podkreślenia. Następnie w nawiasach okrągłych podajemy oddzielone od siebie przecinkami parametry procedury lub funkcji, lub jeśli ich nie ma, to tylko otwieramy i zamykamy nawias, a linię kończymy znakiem dwukropka.

Tak więc załóżmy, że będziemy w przyszłości chcieli napisać procedurę dla Naszego robota, która zajmie się robieniem herbaty o danym smaku. Piszemy zatem:

def zrob_herbate(smak):
   print("Ta procedura zrobi kiedys herbate", smak)

Oczywiście to tylko tzw. zaślepka procedury robiącej herbatę, bo nie znamy przecież szczegółowych instrukcji jakie Nasz robot będzie przyjmował 🙂 Nie mniej jednak to zupełnie wystarczy, by w skuteczny sposób przetestować jej działanie.

zrob_herbate("zielona")
 Ta procedura zrobi kiedys herbate zielona

zrob_herbate("czarna")
 Ta procedura zrobi kiedys herbate czarna

zrob_herbate("ziolowa")
 Ta procedura zrobi kiedys herbate ziolowa

zrob_herbate("cytrynowa")
 Ta procedura zrobi kiedys herbate cytrynowa

Jakie korzyści daje stosowanie procedur i funkcji?

Najważniejszą korzyścią jaką daje stosowanie procedur i funkcji jest z pewnością oszczędność w pisaniu kodu.
Jak widzicie w przykładowej procedurze tylko raz w programie mamy użyte polecenie wydruku, a drukuje ono Nam tekst za każdym razem, gdy wywołujemy Naszą procedurę. Gdy w końcu kiedyś powstanie kompletna wielo-liniowa procedura to oszczędności na wpisaniu kodu będą w ujęciu całego programu olbrzymie.

Druga korzyścią, poniekąd wynikającą z pierwszej, jest możliwość szybkiej zmiany kodu i naprawy błędów czy dodania nowych funkcjonalności.
Dla przykładu uruchamiając program wykorzystujący powyższą procedurę 5 razy, czyli w Naszym przypadku wypisujący tylko komunikat na ekranie, bez zastosowania procedury, musielibyśmy komunikat „Ta procedura zrobi kiedys herbate” napisać 5 razy i jeśli np. chcielibyśmy zamienić słowo herbatę na herbatkę, to również musielibyśmy to zrobić 5 razy. W przypadku zastosowania procedury, wystarczy zmienić tylko w jednym miejscu! To bardzo duże ułatwienie i silny argument by stosować procedury i funkcje praktycznie wszędzie tam, gdzie blok kodu się Nam powtarza.

Trzecią korzyścią oprócz oszczędności miejsca, szybkości wprowadzania zmian jest zmniejszona ilość błędów w programie. To proste, jeśli musisz coś poprawić w kilku miejscach w kodzie to jest spora szansa, że w odpowiednio dużym programie jakieś miejsce pominiesz i kłopot gotowy. Stosując procedury i funkcje – pozbywasz się tego problemu, ponieważ albo wszędzie działa tak jak byś chciał, albo wszędzie jest błąd – jednakże z punktu widzenia programisty to też dobra wiadomość, bo od razu wiadomo w której funkcji czy procedurze należy szukać przyczyny i gdzie poprawić błąd.

Czwartą korzyścią, to już bardziej może dla praktykujących programistów, jest możliwość nazwania części kodu. Po prostu „zamykamy” część programu w postaci procedury nadając mu nazwę. W ten sposób możemy uprościć wygląd Naszego kodu i uczynić go bardziej czytelnym. Taka forma abstrakcji kodu przydaje się szczególnie przy pracy ze starym, np. kodem i pozwala na podzielenie go w logiczny sposób i stopniowe przepisywanie, lub poprawianie.

Jaka jest różnica pomiędzy funkcją a procedurą?

Zwyczajowo przyjęto rozróżniać nazwy funkcja od procedura ze względu na to czy dana konstrukcja zwraca wartość czy też nie. W niektórych językach jest to bardzo konkretne rozróżnienie, natomiast w innych granica pomiędzy funkcją a procedurą się zupełnie zatarła.
Wyjaśnię jednak może na przykładzie co mam na myśli mówiąc o zwracaniu wartości przez funkcję.

Pamiętacie zapewne z ostatniego odcinka o operatorach, operator przypisania. Jak wiemy przypisuje on wartość po prawej stronie zmiennej po lewej stronie. Dlatego wykorzystując ten fakt i mając funkcję, która zwraca Nam wynik, możemy ten wynik od razu przypisać do danej zmiennej. Na przykład zdefiniujmy funkcję, która oblicza Nam obwód koła, gdy parametrem jest promień. W Pythonie możemy to zrobić tak:

def licz_obwod(r):
   return 2*3.14*r;

Dodanie słowa kluczowego return oznacza, że wynik działania które po nim następuje będzie przekazane jako wynik całej funkcji.
Możemy zatem przypisać wynik tej funkcji do zmiennej x i ją wydrukować na ekranie:

x = licz_obwod(5)
 print(x)

albo uprościć zapis pomijając tą tymczasową zmienną i zapisać tak:

print(licz_obwod(5))

Podsumowanie

I to wszystko co przygotowałem dla Was w tym odcinku Programowania dla nieprogramistów! Mam nadzieję, że odcinek się Wam spodobał, jeśli tak to proszę zostawcie łapkę w górę, jeśli nie to łapkę w dół, ale koniecznie wtedy napiszcie dlaczego i co mogę zmienić w przyszłości. Dodatkowo tradycyjnie zapraszam na moje pozostałe kanały społecznościowe, gdzie publikuję dodatkowe materiały, które nie zawsze trafiają na YouTube.
Oczywiście zachęcam gorąco do komentowania, postaram się odpowiedzieć na każdy komentarz, jak i też do subskrypcji aby nie przegapić kolejnych filmów z tej i pozostałych serii edukacyjnych na moim kanale.
Do zobaczenia!