Archiwa kategorii: Moduł pierwszy kursu

M1 L29 Cęść praktyczna zadania

Poniżej przedstawimy kilka zadań ułatwiających utrwalenie materiału poznanego w ramach obecnego modułu. Są one dość otwarte i mogą być zrealizowane w dowolny sposób – głównym celem jest tutaj praktyka.

Zadania

1. Wypisz na ekranie napis powitalny w rodzaju „Witam, nazywam się X i Y”, gdzie X i Y będą zmiennymi zawierającymi Twoje imię i nzawisko.

2. Zapisz obecną datę w postaci trzech zmiennych liczbowych. Następnie wypisz ją na konsoli jako tekst „Dzisiaj jest …”, rozdzielając części składowe daty kropkami.

3. Znajdź największą z trzech zmiennych.

4. Stwórz trzy zmienne liczbowe i sprawdź czy są podzielne przez 9.

5. Sprawdź czy lista zmiennych tekstowych zawiera zadany napis.

6. Stwórz listę złożoną z kilkunastu liczb, a następnie oblicz ich średnią.

7. Stwórz listę zawierającą nazwy miesięcy. Następnie napisz kod, który poda długość nazwy każdego z miesięcy.

8. Oblicz silnie z 10, korzystając z pętli.

9.  Jednym z popularnych pytań rekrutacyjnych dla programistów jest tzw. „FizzBuzz”. Polega on na przejściu przez listę liczb od 1 do 100. Jeśli dana liczba jest podzielna przez 3 należy wypisać „Fizz”, dla liczb podzielnych przez 5 „Buzz”, dla podzielnych przez obie te wartości – „Fizz Buzz”. W przeciwnym razie, wypisujemy wartość liczby. Napisz kod, który zrealizuje takie zadanie.

10. Zadanie 9 wykonaj w przeciwnej kolejności, tj. od 100 do 1.

 

M1 L28 Podsumowanie

Zapoznaliśmy się z podstawowymi metodami przechowywania i modyfikacji danych programistycznych. Wiedza ta jest niezbędna dla każdego programisty i wykorzystywana na co dzień, bez wyjątku. Nie ma znaczenia na jaki język programowania ostatecznie się zdecydujemy – ogólne zasady są niezmienne. Szczegółowa implementacja pętli w Pythonie jest inna niż w Javie, ale sposób działania pozostanie ten sam.

Oczywiście jest to tylko zalążek faktycznej wiedzy programistycznej, przedstawiany na bardzo uproszczonych przykładach, ale jego opanowanie jest niezbędne. W tym celu na kolejnym ekranie zostanie przedstawionych kilka zadań do wykonania na własną rękę. Część z nich może wydać się nieco bardziej skomplikowana niż pokazane do tej pory przykłady, ale zdobyta przez nas dotychczas wiedza jest w zupełności wystarczająca do ich wykonania.

M1 L27 Pętle z wbudowanym licznikiem

Przy okazji pętli while przestawiliśmy koncepcje „licznika” – zmiennej, którą definiowaliśmy wewnątrz pętli i zwiększaliśmy w miarę kolejnych powtórzeń. Ręczne tworzenie takiego licznika jest jednak dość niewygodne, można łatwo o nim zapomnieć lub zmienić wartość w nieprawidłowy sposób.

Większość języków programowania oferuje opcje automatycznego tworzenia liczników dla pętli typu for. W przypadku Pythona, służy do tego operator range, który generuje listę wartości przez którą przejdzie pętla.

Konstrukcja taka przejdzie przez wartości od 0 do 4 – jak pamiętamy, pozycje listy zaczynają się od zera, więc ostatnia wartość zawsze będzie o 1 mniejsza od zadeklarowanej w nawiasie.

Możemy również zastosować taką pętlę dla już istniejących list. Przykład poniżej pokazuje zastosowanie licznika w celu bezpośredniego odwoływania się do listy, jak również numerowania jej pozycji. Jest to dość częsty sposób użycia takiej pętli, szczególnie gdy chcemy dokładnie obejrzeć poszczególne elementy, wraz z ich pozycją.

Możliwa jest również wersja z dwoma parametrami – pierwszy z nich określi początek generowanej listy, a drugi koniec.

M1 L26 Pętle i listy – ciąg dalszy

Posługując się listami na co dzień, często potrzebujemy przejrzeć całą ich zawartość i wykonać konkretne operację na poszczególnych elementach – być może uzależniając je też od odpowiednich warunków logicznych.

Pętle są stworzone do tego typu rozwiązań – w szczególności druga wersja pętli, którą poznany teraz. Do jej stworzenia służy słowo kluczowe FOR oraz in.

for <zmienna> in <lista>:

                 <instrukcja 1>

                 <instrukcja 2>

                 …

Pętla takiej postaci przechodzi przez poszczególne elementy listy i wykonuje na nich zadane instrukcje. Konstrukcja <zmienna> jest traktowana przez program jako tymczasowa nazwa, przydzielona do obecnego elementu listy, np.

Jeśli posługujemy się zagnieżdżonymi listami, potrzebujemy również zagnieździć pętle:

M1 L25 ZAGNIEŻDZANIE LIST

Zagnieżdżenie możliwe jest również w przypadku list, chociaż pełni tam nieco inną funkcję i jest zrealizowane w inny sposób.

Załóżmy, iż chcemy stworzyć planszę do gry w kółko i krzyżyk, czyli kwadrat o rozmiarach 3 x 3. Listy wydają się tutaj naturalnym rozwiązaniem – mamy trzy wiersze, w każdym z nich trzy pola. Stosując dotychczas poznane metody tworzenia list możemy uzyskać kod w rodzaju:

Wydaje się to dość logiczne i zrozumiałe. W miarę rozwoju gry, zmieniamy wartości w stosownych listach i mamy pełną kontrolę nad jej przebiegiem. W sumie mamy do czynienia z 9 zmiennymi, co jest ilością dość łatwą do opanowania.

Co jednak, gdy interesują nas szachy? Potrzebujemy wówczas już 8 różnych tablic, każda z nich po 8 elementów. Gra w statki? 10 i 10. Gra w Go? 19 x 19.

Dla takich sytuacji służą zagnieżdżone listy, czyli listy składające się z innych list, np.

Zagnieżdżone listy dwuwymiarowe są też czasem nazywane macierzami. Dla większej jasności możemy przedstawić taką strukturę w pionie:

Widzimy wyraźny podział na wiersze i kolumny, bez konieczności tworzenia nadmiarowych zmiennych. Chcąc odwołać się do odpowiedniej pozycji, stosujemy znaną nam notację nawiasów kwadratowych – tym razem dwukrotnie. W pierwszym nawiasie będzie to wiersz, w drugim kolumna, np.

M1 L24 ZAGNIEŻDŻANIE PĘTLI

Przedstawione do tej pory pętle działały na jednym poziomie. Jeśli warunek logiczny był spełniony, program wykonywał zadane instrukcje, w przeciwnym razie kończył działanie. Czasem jednak potrzebujemy dodatkowego poziomu warunków, by zrealizować pożądaną przez nas funkcjonalność.

Załóżmy, iż w utworzonej przez nas pętli od 1 do 1000 chcemy wypisywać tylko liczby podzielne przez 3. W tym celu musimy połączyć pętle z instrukcjami warunkowymi:

Jest to rozwinięcie wspomnianego wcześniej “zagnieżdżenia”. Dodając kolejny poziom wcięcia w kodzie tworzymy instrukcje zależne od wykonania innych instrukcji, które z kolei mają swoje instrukcje nadrzędne itd. Pozwala to na tworzenie rozbudowanych alternatyw przebiegu programu i uzyskanie opcji, które normalnie byłyby niedostępne.

Ilość zagnieżdżeń może być dowolna, w zależności od naszych potrzeb. Skomplikowane programy mają często po kilka poziomów wcięć i złożoną sieć powiązań między nimi, zwykle niemożliwą do zrealizowania w inny sposób.

Należy przy tym pamiętać, że silnie zagnieżdżony kod może być zupełnie funkcjonalny, ale stanie się praktycznie nieczytelny dla innych użytkowników. Nawet tak trywialne kwestie jak szerokość monitora mogą spowodować konieczność przewijania ekranu lub zawijania wierszy, by odczytać cały kod. Zawsze należy zastanowić się, czy nie da się zredukować ilości zagnieżdżeń i zrealizować to samo za pomocą innych warunków logicznych.

M1 L23 PĘTLE CD

Pętle są bardzo użytecznym narzędziem, które może jednak spowodować problemy w działaniu naszego programu. Dotychczas, jeśli w programie występował błąd, otrzymywaliśmy stosowny komunikat na konsoli i przerywał on swoje działanie. W przypadku pętli, sytuacja może być bardziej złożona.

Zmodyfikujmy nieznacznie kod poprzedniego programu. Załóżmy, że nasz warunek logiczny wygląda teraz następująco:

Otrzymamy listę stale rosnących liczb, która wydaje się nie mieć końca i uniemożliwia zatrzymanie pracy programu. Musimy dokonać tego ręcznie, korzystając z kombinacji klawiszy CTRL+C.

Otrzymaliśmy tzw. nieskończoną pętle – konstrukcję, która będzie wykonywała się bez końca, gdyż warunek logiczne zawsze będzie prawdziwy. W ekstremalnych przypadkach może to nawet spowodować zupełne zawieszenie komputera, zajmując wszystkie wolne zasoby na potrzebę wykonania jednego programu

Należy przy tym zwrócić uwagę, że taki program działa „prawidłowo” i wykonuje dokładnie to co mu zleciliśmy. Środowisko programistyczne nie uzna takiej sytuacji za „błąd” i nie ostrzeże nas o potencjalnym problemie. Z tego też powodu nieskończone pętle są stosunkowo częstym błędem, nawet wśród doświadczonych programistów. Wystarczy jeden błędnie postawiony znak nierówności lub pominięty licznik, co może łatwo pozostać niezauważone, gdy mamy do czynienia z setkami linii kodu.

M1 L22 PĘTLE

Pętle są kolejnym kluczowym elementem programowania. Służą do cyklicznego wykonywania ciągu podobnych instrukcji, w ramach określonego warunku logicznego. Jest to sytuacja z którą spotykamy się w większości programów i którą musimy wykonać szybko i wyda.

Załóżmy, iż chcemy wypisać na konsoli liczby od 1 do 4. Z dotychczas poznanych instrukcji wiemy, iż możemy to zrobić w postaci:

Program taki zadziała poprawnie, jednak dość łatwo zauważyć, że nie jest to szczególnie optymalne rozwiązanie. Dla czterech liczb jest to jeszcze stosunkowo czytelne i łatwe do realizacji. Co jednak w sytuacji, gdy interesują nas wartości od 1 do 1000? Tysiąc niemal identycznych instrukcji uczyni nasz program praktycznie nieczytelnym – nie mówiąc już o potencjalnych błędach, które mogliśmy popełnić.

Zauważmy, że działanie programu tak naprawdę sprowadza się do wypisania zmiennej, którą cały czas zwiększamy o jeden. Pętle są stworzone do tego typu sytuacji – ich zadaniem jest wykonywanie zapisywanych w nich instrukcji do momentu spełnienia zadanego warunku logicznego. (czyli osiągnięcia liczby 1000)

Podstawowa struktura pętli jest dość podobna do instrukcji warunkowej i wygląda następująco:

while(warunekLogiczny):

                 instrukcja1

                 instrukcja2…

Dopóki zadany warunek logiczny przyjmuje wartość True, dopóty wykonywana będzie pętla. Na przykładzie zadanego wcześniej problemu:

X pełni rolę swoistego licznika, określającego liczbę powtórzeń pętli. Z każdym przebiegiem zwiększa się o 1, aż osiągnie wartość 1001 i warunek logiczny otrzyma wartość False.

Zadanie

1. Wypisz liczby od 1000 do 1.

M1 L20 OPERACJE NA LISTACH

Listy są elementami bardziej złożonymi niż dotychczas poznane zmienne i obsługuje się je za pomocą innych instrukcji. Wprawdzie na poszczególnych elementach można wykonywać standardowe działania takie jak dodawanie, konkatenacja napisów itd., to nie są one dopuszczalne dla całej listy.

Dwie podstawowe operacje na listach to dodawanie i usuwanie elementów.

Pierwszą z nich wykonuje się poprzez słowo kluczowe append(zmienna), które dodaje nowy element na koniec listy, np.

Jeśli chcemy umieścić element w innym miejscu, musimy skorzystać z instrukcji insert(pozycja,zmienna)

W celu usunięcia elementu, musimy podać jego wartość i użyć opcji remove(zmienna).

Zadania

1. Stwórz pustą listę i dodaj do niej nazwy dni tygodnia.

2. Usuń pozycję listy, by otrzymać dni weekendu.