class: center, middle, inverse, title-slide .title[ # Podstawy programowania ] .subtitle[ ## Programowanie ] .author[ ### © Łukasz Wawrowski ] --- # Wprowadzenie - mniej języka naturalnego, więcej operatorów - komunikacja człowiek-komputer - rozwiązywanie bardziej złożonych problemów za pomocą: - funkcji - warunków - pętli --- class: inverse, middle, center # Funkcje --- # Funkcje > Metoda Copy'ego i Paste'a jest potężnym narzędziem, ale nie powinna być nadużywana Funkcję ograniczają potrzebę kopiowania kodu i ułatwiają wprowadzanie zmian. 1. Funkcję zawierającą dużo kodu można ładnie nazwać, co ułatwia rozumienie programu 2. W przypadku potrzeby wprowadzenia zmian wystarczy to zrobić tylko w jednym miejscu 3. Unikanie problemów przy kopiowaniu np. zamiana nazwy zmiennej --- # Przepis na funkcję Stworzenie funkcji wymaga: 1. wymyślenia nazwy funkcji 2. określenia elementów wejściowych 3. umieszczenia kodu w ciele funkcji --- # Dobre praktyki tworzenia funkcji - nazwy funkcji powinny być czasownikami - ustalona notacja: podkreślnik vs. camelCase - wspólny przedrostek ```r # Good input_select() input_checkbox() input_text() # Not so good select_input() checkbox_input() text_input() ``` --- # Składnia funkcji ```r oblicz_srednia <- function(liczby, zaokraglenie = 2){ srednia <- mean(liczby) srednia_zaokr <- round(x = srednia, digits = zaokraglenie) return(srednia_zaokr) } temp <- c(-1, 7, 9, 11, 8, 4, 3, 2) oblicz_srednia(temp) ``` ``` ## [1] 5.38 ``` ```r oblicz_srednia(liczby = temp, zaokraglenie = 0) ``` ``` ## [1] 5 ``` Funkcje to programowanie na wysokim poziomie abstrakcji. Tworzymy obliczenia dla _jakichś_ danych wejściowych, a wywołujemy je na _konkretnych_ obiektach. --- # Przykład Obliczenie wskaźnika dla wybranych kolumn: `$$\text{wsk}=\frac{min(x)-max(x)}{\bar{x}}$$` --- # Bardzo złe pomysły ```r # Too short f() # Not a verb, or descriptive my_awesome_function() # Never do this! col_mins <- function(x, y) {} rowMaxes <- function(y, x) {} # Don't do this! T <- FALSE c <- 10 mean <- function(x) sum(x) ``` [Źródło](https://r4ds.had.co.nz/functions.html) --- class: inverse # Zadanie Stwórz funkcję, która będzie normalizować wartości cechy w zakresie od 0 do 1 według wzoru: `$$z = \frac{x - min(x)}{max(x)-min(x)}$$`
−
+
10
:
00
--- class: inverse, middle, center # Warunki --- # Wykonywanie warunkowe Za pomocą instrukcji if możemy warunkowo wykonywać kod. Ogólna postać jest następująca: ```r if(warunek1){ # kod wykonany jeśli warunek jest równy TRUE } else if(warunek2) { # kod wykonany jeśli warunek1 jest równy FALSE, a warunek2 jest równy TRUE } else { # kod wykonany jeśli warunek1 i warunek2 jest równy FALSE } ``` Warunek musi zwracać wartość logiczną `TRUE` albo `FALSE`. Szczególnie przydatne w funkcjach do sprawdzania poprawności argumentów wejściowych (patrz też: [`stopifnot`](https://rdrr.io/r/base/stopifnot.html)). --- # Porównywanie ```r x <- 4 x ``` ``` ## [1] 4 ``` ```r x == 4 ``` ``` ## [1] TRUE ``` ```r length(x) > 0 ``` ``` ## [1] TRUE ``` ```r x == NA ``` ``` ## [1] NA ``` ```r is.na(x) ``` ``` ## [1] FALSE ``` --- # Operatory łączenia Dopuszczalne operatory łączenia: `&&` (i), `||` (lub). ```r x <- 4 x ``` ``` ## [1] 4 ``` ```r x > 2 && x < 6 ``` ``` ## [1] TRUE ``` ```r x > 2 && x < 3 ``` ``` ## [1] FALSE ``` ```r x > 2 || x < 3 ``` ``` ## [1] TRUE ``` --- # Przykład Sprawdzenie czy liczba jest mniejsza, większa od 0 czy równa 0. --- class: inverse # Zadanie Napisz funkcję, która na podstawie wartości liczby który zwróci różne komunikaty: - liczba podzielna przez 3, - liczba podzielna przez 5, - liczba podzielna przez 3 i 5, - liczba niepodzielna ani przez 3 ani przez 5. Operator zwracający resztę z dzielenia to `%%`: ```r 10 %% 2 ``` ``` ## [1] 0 ``` ```r 10 %% 3 ``` ``` ## [1] 1 ```
−
+
15
:
00
--- class: inverse, middle, center # Pętle --- # Pętla - powtarzanie danej akcji z innymi danymi wejściowymi - w R zaimplementowane są pętle: for, while, repeat - zamiast pętli można wektoryzować przetwarzanie --- # Pętla for Pętla składa się z trzech elementów: - wyjście - zarezerwowanie odpowiedniej ilości miejsca w pamięci na wynik - sekwencja - iterator i liczba wykonywanych razy (zakres) - ciało - przetwarzanie, którego wynik za każdym przebiegiem pętli będzie inny ```r for(iterator in zakres){ # ciało pętli } ``` --- # Wypisanie nazw miesięcy ```r for(month in 1:length(month.name)){ print(month.name[month]) } ``` ``` ## [1] "January" ## [1] "February" ## [1] "March" ## [1] "April" ## [1] "May" ## [1] "June" ## [1] "July" ## [1] "August" ## [1] "September" ## [1] "October" ## [1] "November" ## [1] "December" ``` --- # Wypisanie nazw miesięcy ```r for(month in seq_along(month.name)){ print(month.name[month]) } ``` ``` ## [1] "January" ## [1] "February" ## [1] "March" ## [1] "April" ## [1] "May" ## [1] "June" ## [1] "July" ## [1] "August" ## [1] "September" ## [1] "October" ## [1] "November" ## [1] "December" ``` --- # Przykład 100 krotny rzut kostką. ??? ```r wynik_kostka <- numeric(100) for(rzut in seq_along(wynik_kostka)){ wynik_kostka[rzut] <- sample(1:6, 1) } table(wynik_kostka) ``` ``` ## wynik_kostka ## 1 2 3 4 5 6 ## 19 12 18 18 16 17 ``` --- # Wektoryzacja Ile liczb w wektorze jest dodatnich. ```r liczby <- sample(x = seq(-100,100,1), size = 10000, replace = T) ``` .pull-left[ ```r f_petla <- function(x){ wynik <- logical(length(x)) for(i in seq_along(x)){ wynik[i] <- x[i] > 0 } return(sum(wynik)) } f_petla(liczby) ``` ``` ## [1] 4936 ``` ] .pull-right[ ```r f_wektor <- function(x){ wynik <- x > 0 return(sum(wynik)) } f_wektor(liczby) ``` ``` ## [1] 4936 ``` ] --- # Wektoryzacja ```r microbenchmark::microbenchmark(f_petla(liczby), f_wektor(liczby)) ``` ``` ## Unit: microseconds ## expr min lq mean median uq max neval ## f_petla(liczby) 605.902 620.2515 636.55099 625.201 631.7515 1087.501 100 ## f_wektor(liczby) 40.601 48.6510 66.86496 49.602 50.5005 1794.601 100 ``` --- # Inne sposoby na pętle - funkcje z rodziny apply: `lapply`, `sapply`, `vapply` - funkcje `map` z pakietu [purrr](https://purrr.tidyverse.org/) - napisane w C, operujące głównie na listach - przetwarzanie równoległego: pakiet parallel --- class: inverse # Zadanie Napisz pętlę, która wyświetli tekst piosenki [99 bottles of beer on the wall](https://pl.wikipedia.org/wiki/99_Bottles_of_Beer)
−
+
10
:
00