diff options
| -rw-r--r-- | de-de/yaml-de.html.markdown | 2 | ||||
| -rw-r--r-- | elisp.html.markdown | 6 | ||||
| -rw-r--r-- | es-es/visualbasic-es.html.markdown | 2 | ||||
| -rw-r--r-- | lambda-calculus.html.markdown | 2 | ||||
| -rw-r--r-- | pl-pl/java-pl.html.markdown | 1026 | ||||
| -rw-r--r-- | ru-ru/learnvisualbasic-ru.html.markdown | 284 | ||||
| -rw-r--r-- | standard-ml.html.markdown | 3 | ||||
| -rw-r--r-- | visualbasic.html.markdown | 2 | ||||
| -rw-r--r-- | vyper.html.markdown | 867 | 
9 files changed, 2186 insertions, 8 deletions
| diff --git a/de-de/yaml-de.html.markdown b/de-de/yaml-de.html.markdown index d0e3471a..ff45dc8d 100644 --- a/de-de/yaml-de.html.markdown +++ b/de-de/yaml-de.html.markdown @@ -111,7 +111,7 @@ python_komplexe_Zahlen: !!python/komplex 1+2j  # EXTRA YAML TYPEN #  #################### -# Strings and Zahlen sind nicht die einzigen Skalare, welche YAML versteht. +# Strings und Zahlen sind nicht die einzigen Skalare, welche YAML versteht.  # ISO-formatierte Datumsangaben and Zeiangaben können ebenso geparsed werden.  DatumZeit: 2001-12-15T02:59:43.1Z  DatumZeit_mit_Leerzeichen: 2001-12-14 21:59:43.10 -5 diff --git a/elisp.html.markdown b/elisp.html.markdown index 518ad985..f839dac0 100644 --- a/elisp.html.markdown +++ b/elisp.html.markdown @@ -281,7 +281,7 @@ filename: learn-emacs-lisp.el  ;; should stop searching at some point in the buffer, and whether it  ;; should silently fail when nothing is found: -;; (search-forward "Hello" nil 't) does the trick: +;; (search-forward "Hello" nil t) does the trick:  ;; The `nil' argument says: the search is not bound to a position.  ;; The `'t' argument says: silently fail when nothing is found. @@ -295,7 +295,7 @@ filename: learn-emacs-lisp.el      (mapcar 'hello list-of-names)      (goto-char (point-min))      ;; Replace "Hello" by "Bonjour" -    (while (search-forward "Hello" nil 't) +    (while (search-forward "Hello" nil t)        (replace-match "Bonjour"))      (other-window 1)) @@ -306,7 +306,7 @@ filename: learn-emacs-lisp.el  (defun boldify-names ()      (switch-to-buffer-other-window "*test*")      (goto-char (point-min)) -    (while (re-search-forward "Bonjour \\(.+\\)!" nil 't) +    (while (re-search-forward "Bonjour \\(.+\\)!" nil t)        (add-text-properties (match-beginning 1)                             (match-end 1)                             (list 'face 'bold))) diff --git a/es-es/visualbasic-es.html.markdown b/es-es/visualbasic-es.html.markdown index ca00626b..c677c20f 100644 --- a/es-es/visualbasic-es.html.markdown +++ b/es-es/visualbasic-es.html.markdown @@ -4,8 +4,6 @@ contributors:      - ["Brian Martin", "http://brianmartin.biz"]  translators:      - ["Adolfo Jayme Barrientos", "https://github.com/fitojb"] -author: Brian Martin -author_url: https://github.com/fitojb  filename: learnvisualbasic-es.vb  lang: es-es  --- diff --git a/lambda-calculus.html.markdown b/lambda-calculus.html.markdown index a5535d6c..53a7a7cd 100644 --- a/lambda-calculus.html.markdown +++ b/lambda-calculus.html.markdown @@ -85,7 +85,7 @@ Using `IF`, we can define the basic boolean logic operators:  `a OR b` is equivalent to: `λab.IF a T b` -`a NOT b` is equivalent to: `λa.IF a F T` +`NOT a` is equivalent to: `λa.IF a F T`  *Note: `IF a b c` is essentially saying: `IF((a b) c)`* diff --git a/pl-pl/java-pl.html.markdown b/pl-pl/java-pl.html.markdown new file mode 100644 index 00000000..0da449c5 --- /dev/null +++ b/pl-pl/java-pl.html.markdown @@ -0,0 +1,1026 @@ +--- +language: java +filename: LearnJavaPl.java +contributors: +    - ["Jake Prather", "https://github.com/JakeHP"] +    - ["Jakukyo Friel", "https://weakish.github.io"] +    - ["Madison Dickson", "https://github.com/mix3d"] +    - ["Simon Morgan", "https://sjm.io/"] +    - ["Zachary Ferguson", "https://github.com/zfergus2"] +    - ["Cameron Schermerhorn", "https://github.com/cschermerhorn"] +    - ["Rachel Stiyer", "https://github.com/rstiyer"] +    - ["Michael Dähnert", "https://github.com/JaXt0r"] +    - ["Rob Rose", "https://github.com/RobRoseKnows"] +    - ["Sean Nam", "https://github.com/seannam"] +    - ["Shawn M. Hanes", "https://github.com/smhanes15"] +filename: LearnJava.java +translators: +    - ["Jacek Wachowiak", "https://github.com/jacekwachowiak"] +lang: pl-pl +--- + +Java jest współbieżnym, opartym na klasach, obiektowym językiem programowania +ogólnego zastosowania. +[Tu znajdziesz więcej informacji po angielsku.] +(https://docs.oracle.com/javase/tutorial/java/) + +```java +// Pojedyncze komentarze oznaczamy // + +/* +Komentarze wieloliniowe wyglądają tak +*/ + +/** + * Komentarze JavaDoc wygladają w ten sposób. Używane są do opisu klas lub + * różnych właściwości klas. + * Główne właściwości: + * + * @author      Imię i nazwisko (i kontakt np. email) autora. + * @version     Aktualna wersja programu. + * @since       Kiedy ta część programu została dodana. + * @param       Służy do opisu parametrów metody. + * @return      Służy do opisu zwracanej wartości. + * @deprecated  Służy do oznaczenia nieaktualnego lub niezalecanego kodu. + * @see         Linki do innej cześci dokumentacji. +*/ + +// Import klasy ArrayList z paczki java.util +import java.util.ArrayList; +// Import wszystkich klas z paczki java.security +import java.security.*; + +public class LearnJava { + +    // Aby móc uruchomić program w języku java musi on mieć główną metodę jako +    // punkt wejścia. +    public static void main(String[] args) { + +    /////////////////////////////////////// +    // Operacje wejścia/wyjścia (input/output) +    /////////////////////////////////////// + +        /* +        * Wyjście +        */ + +        // System.out.println() służy do wyświetlania linii tekstu. +        System.out.println("Hello World!"); +        System.out.println( +            "Integer: " + 10 + +            " Double: " + 3.14 + +            " Boolean: " + true); + +        // Aby wyświetlić  bez nowej linii użyj System.out.print(). +        System.out.print("Hello "); +        System.out.print("World"); + +        // System.out.printf() służy do łatwego formatowania wyświetlanego elementu. +        System.out.printf("pi = %.5f", Math.PI); // => pi = 3.14159 + +        /* +         * Wejście +         */ + +        // Scanner służy do wczytywania danych +        // niezbędny jest import java.util.Scanner; +        Scanner scanner = new Scanner(System.in); + +        // zczytaj string (tekst) +        String name = scanner.next(); + +        // zczytaj zmienną typu bajt +        byte numByte = scanner.nextByte(); + +        // zczytaj zmienną typu integer - liczba całkowita +        int numInt = scanner.nextInt(); + +        // zczytaj zmienną typu float - liczba zmiennoprzecinkowa +        float numFloat = scanner.nextFloat(); + +        // zczytaj zmienna typu double -liczba zmiennoprzecinkowa +        double numDouble = scanner.nextDouble(); + +        // zczytaj zmienną typu boolowskiego - +        boolean bool = scanner.nextBoolean(); + +        /////////////////////////////////////// +        // Zmienne +        /////////////////////////////////////// + +        /* +        *  Deklaracja zmiennych +        */ +        // Zmienną deklaruje się poprzez <rodzaj> <nazwa> +        int fooInt; +        // Dozwolona jest deklaracja wielu zmiennych tego samego typu na raz +        // rodzaj <nazwa1>, <nazwa2>, <nazwa3> +        int fooInt1, fooInt2, fooInt3; + +        /* +        *  Inicjalizacja zmiennych +        */ + +        // Zmienną inicjalizuje się poprzez <rodzaj> <nazwa> = <wartość> +        int barInt = 1; +        // Możliwe jest zainicjalizowanie wielu zmiennych tego samego typu tą samą wartością +        // rodzaj <nazwa1>, <nazwa2>, <nazwa3> +        // <nazwa1> = <nazwa2> = <nazwa3> = <wartość> +        int barInt1, barInt2, barInt3; +        barInt1 = barInt2 = barInt3 = 1; + +        /* +        *  Rodzaje zmiennych +        */ +        // Bajt - 8-bitowa, zawierająca ujemne wartości zmienna w dwójkowym +        // systemie pozycyjnym +        // (-128 <= byte <= 127) +        byte fooByte = 100; + +        // Jeśli chcemy zinterpretować bajt jako zmienną typu unsigned integer +        // - liczbę całkowitą z wartościami ujemnymi ta operacja może pomóc: +        int unsignedIntLessThan256 = 0xff & fooByte; +        // jako kontrast operacja zmiany typu która może zwrócić wartość ujemną. +        int signedInt = (int) fooByte; + +        // Short - 16-bitowa, zawierająca ujemne wartości zmienna w dwójkowym +        // systemie pozycyjnym (-32,768 <= short <= 32,767) +        short fooShort = 10000; + +        // Integer - 32-bitowa, zawierająca ujemne wartości zmienna w dwójkowym systemie pozycyjnym +        // (-2,147,483,648 <= int <= 2,147,483,647) +        int bazInt = 1; + +        // Long - 64-bitowa, zawierająca ujemne wartości zmienna w dwójkowym +        // systemie pozycyjnym +        // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) +        long fooLong = 100000L; +        // L jest używane do zaznaczenia, że wartość zmiennej jest typu Long; +        // bez L wszystko inne będzie traktowane z założenia jako integer. + +        // Uwaga: byte, short, int and long zawierają ujemne wartości. +        // Nie istnieją odpowiedniki z jedynie pozytywnymi wartościami. +        // Jedynie char jest 16-bitowym typem zmiennej, który akceptuje tylko +        // wartości nieujemne. + +        // Float - 32-bitowy typ zmiennoprzecinkowy zgodnie z IEEE 754 +        // Floating Point 2^-149 <= float <= (2-2^-23) * 2^127 +        float fooFloat = 234.5f; +        // f or F jest używane aby zaznaczyć, że dana zmienna jest typu float; +        // w przeciwnym razie będzie ona traktowana jako double. + +        // Double -  64-bitowy typ zmiennoprzecinkowy zgodnie z IEEE 754 +        // Floating Point 2^-1074 <= x <= (2-2^-52) * 2^1023 +        double fooDouble = 123.4; + +        // Typ boolowski - true/prawda & false/fałsz +        boolean fooBoolean = true; +        boolean barBoolean = false; + +        // Char - pojedynczy 16-bitowy symbol Unicode +        char fooChar = 'A'; + +        // zmienne zadeklarowane z użyciem final nie mogą być edytowane, +        final int HOURS_I_WORK_PER_WEEK = 9001; +        // ale możliwa jest późniejsza inicjalizacja. +        final double E; +        E = 2.71828; + +        // BigInteger - Nieedytowalny typ zmiennej o nieograniczonej długości +        // dla liczb całkowitych +        // +        // BigInteger jest typem zmiennej, który pozwala na operacje na liczbach całkowitych dłuższych niż 64 bity. +        // Liczby są przechowywane jako tablica bajtów +        // i modyfikowane za pomocą funkcji wbudowanych w BigInteger +        // +        // BigInteger może być zainicjalizowany za pomocą tablicy bajtów lub jako string. +        BigInteger fooBigInteger = new BigInteger(fooByteArray); + +        // BigDecimal - Nieedytowalny typ zmiennej o nieograniczonej długości dla +        // liczb zmiennoprzecinkowych +        // +        // BigDecimal zaiwera 2 części: typ integer o arbitralnej precyzji bez skalowania +        // oraz 32-bitową skalę +        // +        // BigDecimal pozwala programiście na całkowitą kontrolę zaokrąglenia dziesiętnego. +        // Zalecane jest używanie BigDecimal z wartościami walut. +        // oraz tam, gdzie absolutna dokładność jest niezbędna. +        // +        // BigDecimal można zainicjalizowac używając int, long, double or String +        // a także inicjalizując nieprzeskalowaną wartość (BigInteger) i skalę (int). +        BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt); + +        // Uwaga na konstruktor, który przyjmuje float lub double jako, że +        // niedokładność float/double będzie przeniesiona do BigDecimal. +        // Zalecane jest uzywanie konstruktora typu String gdy konieczne jest +        // uzyskanie absolutnej precyzji. +        BigDecimal tenCents = new BigDecimal("0.1"); + +        // String - zmienna tekstowa +        String fooString = "Tutaj jest mój string!"; + +        // \n jest symbolem karetki, która rozpoczyna nową linę +        String barString = "Wyświetlanie w nowej linii?\nNie ma problemu!"; +        // \t jest symbolem tabulatora, który dodaje odstęp. +        String bazString = "Chesz dodać tabulator?\tBez problemu!"; +        System.out.println(fooString); +        System.out.println(barString); +        System.out.println(bazString); + +        // Budowanie Stringów +        // #1 - za pomocą operatora dodawania +        // To jest podstawowy sposób (zoptymalizowany) +        String plusConcatenated = "Stringi mogą " + "być łączone " + "operatorem +."; +        System.out.println(plusConcatenated); +        // Wyjście: Stringi będą połączone operatorem +. + +        // #2 - za pomocą StringBuilder +        // Ten sposób nie tworzy żadnych pośrednich stringów, jedynie zachowuje +        // części i wiąże je po kolei gdy wywołane jest toString(). +        // Wskazówka: Ta klasa nie jest bezpieczna z punktu widzenia wątków. +        // Bezpieczną alternatywą jest (wiążąca się ze spadkiem wydajności) +        // StringBuffer. +        StringBuilder builderConcatenated = new StringBuilder(); +        builderConcatenated.append("Możesz "); +        builderConcatenated.append("użyć "); +        builderConcatenated.append("klasy StringBuilder."); +        System.out.println(builderConcatenated.toString()); // dopiero tutaj +        //budowany jest string +        // Wyjście: Używany jest StringBuilder. + +        // StringBuilder jest wydajny, gdy połączony string nie jest używany aż do końcowego przetworzenia. +        StringBuilder stringBuilder = new StringBuilder(); +        String inefficientString = ""; +        for (int i = 0 ; i < 10; i++) { +            stringBuilder.append(i).append(" "); +            inefficientString += i + " "; +        } +        System.out.println(inefficientString); +        System.out.println(stringBuilder.toString()); +        // inefficientString wymaga dużo więcej pracy przy stworzeniu ponieważ +        // tworzy string przy każdej iteracji. +        // Proste łączenie za pomocą + jest kompilowane do StringBuilder i +        // toString(). Unikaj łączenia stringów w pętlach. + +        // #3 - za pomocą String formatter +        // Inna możliwość, szybka i czytelna. +        String.format("%s wolisz %s.", "A może", "String.format()"); +        // Wyjście: Być może wolisz String.format(). + +        // Tablice +        // Rozmiar tablicy musi być określony przy stworzeniu. +        // Podane poniżej sposoby są dozwolone prz deklaracji tablicy +        // <rodzaj>[] <nazwa> = new <rodzaj>[<rozmiar>]; +        // <rodzaj> <nazwa>[] = new <rodzaj>[<rozmiar>]; +        int[] intArray = new int[10]; +        String[] stringArray = new String[1]; +        boolean boolArray[] = new boolean[100]; + +        // Inny sposób deklaracji i inicjalizacji tablicy +        int[] y = {9000, 1000, 1337}; +        String names[] = {"Bob", "John", "Fred", "Juan Pedro"}; +        boolean bools[] = {true, false, false}; + +        // Indeksowanie tablicy - dostęp do elementów +        System.out.println("intArray @ 0: " + intArray[0]); + +        // Tablice zaczynają się z indeksem 0 i są edytowalne. +        intArray[1] = 1; +        System.out.println("intArray @ 1: " + intArray[1]); // => 1 + +        // Inny typ zmiennej, z którymi warto się zapoznać +        // ArrayLists - Tablice z większą funkcjonalnością +        //              i zmiennym rozmiarem. +        // LinkedLists - Dwustronnie połączone listy. Wszystkie operacje +        //               na listach zaimpllementowane. +        // Maps - Mapy zawierające klucz i wartość. Mapa jest interfejsem +        //        i nie może zostać zainicjalizowana. +        //        Rodzaj klucza i wartości dla mapy musi zostać określony +        //        przy inicjalizacji implementującej mapę klasy +        //        Każdy klucz przypisany jest do tylko jednej wartości, +        //        każdy klucz może wystąpić tylko raz (brak duplikatów). +        // HashMaps - Używa tablicy hashów do implementacji interfejsu mapy +        //            Pozwala to na użycie podstawowych operacji, jak +        //            get i insert, które pozostają niezmiennie wydajne +        //            czasowo nawet dla dużych zestawów danych +        // TreeMap - Mapa posortowana przez klucze. Każda modyfikacja +        //           utrzymuje sortowanie, zdefiniowane przez komparator +        //           dodany przy inicjalizacji lub porównanie każdego obiektu +        //           jeśli zaimplementowany jest interfejs Comparable. +        //           Niepowodzenie kluczy wimplemntacji Comparable połączone +        //           z niepowodzeniem dostarczenia komparatora spowoduje +        //           ClassCastExceptions. +        //           Dodawanie i usuwanie kosztuje O(log(n)) czasu, +        //           zalecane jest nieużywanie tego typu jeżeli sortowanie +        //           nie jest przydatne. + +        /////////////////////////////////////// +        // Operatory +        /////////////////////////////////////// +        System.out.println("\n->Operatory"); + +        int i1 = 1, i2 = 2; // Skrót dla wielokrotnych deklaracji + +        // Arytmetyka jest prosta +        System.out.println("1+2 = " + (i1 + i2)); // => 3 +        System.out.println("2-1 = " + (i2 - i1)); // => 1 +        System.out.println("2*1 = " + (i2 * i1)); // => 2 +        System.out.println("1/2 = " + (i1 / i2)); // => 0 (int/int zwraca int) +        System.out.println("1/2.0 = " + (i1 / (double)i2)); // => 0.5 + +        // Modulo +        System.out.println("11%3 = "+(11 % 3)); // => 2 + +        // Porównania +        System.out.println("3 == 2? " + (3 == 2)); // => false +        System.out.println("3 != 2? " + (3 != 2)); // => true +        System.out.println("3 > 2? " + (3 > 2)); // => true +        System.out.println("3 < 2? " + (3 < 2)); // => false +        System.out.println("2 <= 2? " + (2 <= 2)); // => true +        System.out.println("2 >= 2? " + (2 >= 2)); // => true + +        // Operacje boolowskie +        System.out.println("3 > 2 && 2 > 3? " + ((3 > 2) && (2 > 3))); // => false +        System.out.println("3 > 2 || 2 > 3? " + ((3 > 2) || (2 > 3))); // => true +        System.out.println("!(3 == 2)? " + (!(3 == 2))); // => true + +        // Operacje na bitach! +        /* +        ~      Odwrócenie bitów +        <<     Przesunięcie w lewo +        >>     Przesunięcie w prawo, arytmetyczne/dla wartości ujemnych -signed +        >>>    Przesunięcie w prawo, logiczne/dla wartości dodatnich - unsigned +        &      Bitowe AND +        ^      Bitowe XOR +        |      Bitowe OR +        */ + +        // Operatory inkrementacji +        int i = 0; +        System.out.println("\n->In/De-krementacja"); +        // Operatory ++ i -- zwiększają lub zmniejszają o 1 daną wartość. +        // Jeżeli używane są przed zmienną, wykonywane są przed powrotem zmiennej. +        // Użyte po zmiennej najpierw zwracają zmienną a następnie dokonują +        // zmiany wartości. +        System.out.println(i++); // i = 1, wyświetli 0 (post-increment) +        System.out.println(++i); // i = 2, wyświetli 2 (pre-increment) +        System.out.println(i--); // i = 1, wyświetli 2 (post-decrement) +        System.out.println(--i); // i = 0, wyświetli 0 (pre-decrement) + +        /////////////////////////////////////// +        // Przepływ sterowania +        /////////////////////////////////////// +        System.out.println("\n->Przepływ sterowania"); + +        // Instrukcja if wygląda jak w c +        int j = 10; +        if (j == 10) { +            System.out.println("Wyświetlam się"); +        } else if (j > 10) { +            System.out.println("A ja nie"); +        } else { +            System.out.println("Ja też nie"); +        } + +        // Pętla while +        int fooWhile = 0; +        while(fooWhile < 100) { +            System.out.println(fooWhile); +            // Licznik jest zwiększany +            // Iteruje 100 razy, fooWhile 0,1,2...99 +            fooWhile++; +        } +        System.out.println("Wartość fooWhile: " + fooWhile); + +        // Pętla do while +        int fooDoWhile = 0; +        do { +            System.out.println(fooDoWhile); +            // Licznik jest zwiększany +            // Iteruje 99 razy, fooDoWhile 0->99 +            fooDoWhile++; +        } while(fooDoWhile < 100); +        System.out.println("Wartość fooDoWhile: " + fooDoWhile); + +        // Pętla for +        // struktura pętli for => for(<początek>; <warunek>; <krok>) +        for (int fooFor = 0; fooFor < 10; fooFor++) { +            System.out.println(fooFor); +            // Iteruje 10 razy, fooFor 0->9 +        } +        System.out.println("Wartość fooFor: " + fooFor); + +        // Wyjście z zagnieżdżonej, oznaczonej pętli for +        outer: +        for (int i = 0; i < 10; i++) { +          for (int j = 0; j < 10; j++) { +            if (i == 5 && j ==5) { +              break outer; +              // wychodzi z zewnętrznej pętli zamiast jednynie z aktualnej z +              // powodu oznaczenia +            } +          } +        } + +        // Pętla for each +        // Pętla for each może iterować tablice jak i obiekty +        // które implementują interfejs Iterable. +        int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9}; +        // Struktura for each => for (<element> : <obiekt iterowany>) +        // należy rozumieć jako: dla każdego elementu w obiekcie iterowanym +        // uwaga: typ zdefiniowango elementu musi się zgadzać z typem w +        //obiekcie iterowanym. +        for (int bar : fooList) { +            System.out.println(bar); +            //Iteruje 9 razy i wyświetla 1-9 w nowych liniach +        } + +        // Switch Case +        // Switch (przełącznik) działa z zmiennymi typu byte, short, char, int. +        // Działa również z enumeratorami (zobacz typ Enum), +        // klasą String, i kilkoma specjalnymi klasami które zawierają typy +        // podstawowe: Character, Byte, Short, and Integer. +        // Z wersją Java 7 i wyższymi możliwe jest użycie typu String. +        // Uwagga: Pamiętaj, że nie dodając "break" na końcu danego case +        // spowoduje przejście do następnego (jeżeli spełniony jest warunek). +        int month = 3; +        String monthString; +        switch (month) { +            case 1: monthString = "Styczeń"; +                    break; +            case 2: monthString = "Luty"; +                    break; +            case 3: monthString = "Marzec"; +                    break; +            default: monthString = "Inny miesiąc"; +                     break; +        } +        System.out.println("Wynik Switch Case : " + monthString); + + +        // Try-with-resources (Java 7+) +        // Try-catch-finally działa zgodnie z oczekiwaniami jednakże w Java 7+ +        // dodatkowo jest dostępny try-with-resources statement. +        // Try-with-resources upraszcza try-catch-finally automatycznie +        // usuwając zasoby. + +        // Aby użyć try-with-resources, użyj instancji klasy +        // w części "try". Klasa musi implementować java.lang.AutoCloseable. +        try (BufferedReader br = new BufferedReader(new FileReader("foo.txt"))) { +            // Tutaj możesz spróbować wywołac wyjątek. +            System.out.println(br.readLine()); +            // W Java 7 zasoby będą zawsze usuwane nawet jeśli nastąpi wyjątek. +        } catch (Exception ex) { +            // Zasób będzie usunięty zanim wykona się catch. +            System.out.println("readLine() nie powiódł się."); +        } +        // Nie ma potrzeby używać sekcji "finally", jako że BufferedReader +        // został już zamknięty. Ten sposób może zostać użyty aby uniknąć +        // pewnych wartości brzegowych gdzie "finally" nie zostałoby wywołane +        // Więcej na ten temat po angielsku: +        // https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html + + +        // Skrócone instrukcje warunkowe +        // Dozwolone jest użycie operatora '?' aby szybko sprawdzić warunek +        // logiczny. Rozumiane jest to jako "Jeśli (warunek) jest spełniony, użyj +        // <pierwszej wartości>, inaczej, użyj <drugiej wartości>" +        int foo = 5; +        String bar = (foo < 10) ? "A" : "B"; +        System.out.println("bar : " + bar); // Wyśwletli "bar : A", poineważ +        // warunke jest spełniony. +        // Lub prościej +        System.out.println("bar : " + (foo < 10 ? "A" : "B")); + + +        //////////////////////////////////////// +        // Konwersja typów danych +        //////////////////////////////////////// + +        // Konwersja danych + +        // Konwersja String do Integer +        Integer.parseInt("123");//zwraca zmienna typu Integer o wartości "123" + +        // Konwersja Integer do String +        Integer.toString(123);//zwraca zmienną typu String o wartości 123 + +        // Inne konwersje możesz sprawdzić dla klas: +        // Double +        // Long +        // String + +        /////////////////////////////////////// +        // Klasy i funkcje +        /////////////////////////////////////// + +        System.out.println("\n->Klasy & Funkcje"); + +        // (definicja klasy Rower nieco niżej) + +        // Użyj new aby zainstancjonować klasę +        Rower trek = new Rower(); + +        // Wywoływanie metod klasy +        trek.predkoscZwieksz(3); // Zawsze używaj settera i gettera jako metod +        trek.setPedalowanie(100); + +        // toString zwraca reprezentację typu String tego obiektu. +        System.out.println("trek info: " + trek.toString()); + +        // Inicjalizacja za pomocą podwójnego nawiasu +        // Język Java nie zawiera możliwości stworzenia statycznej kolekcji +        // Dlatego zwykle odbywa się to w ten sposób: +        private static final Set<String> KRAJE = new HashSet<String>(); +        static { +           KRAJE.add("DANIA"); +           KRAJE.add("SZWECJA"); +           KRAJE.add("FINLANDIA"); +        } + +        // Jest jednak sprytny sposób aby łatwiej osiągnąc ten sam efekt +        // używając czegoś nazywanego Double Brace Initialization - +        // inicjalizacja za pomocą podwójnego nawiasu. +        private static final Set<String> KRAJE = new HashSet<String>() {{ +            add("DANIA"); +            add("SZWECJA"); +            add("FINLANDIA"); +        }} + +        // Pierwszy nawias tworzy nową klasę AnonymousInnerClass, +        // drugi deklaruje instancję bloku inicjalizacji. Blok ten +        // jest wywoływany gdy wewnętrzna, anonimowa klasa jest tworzona. +        // Dany sposób działa nie tylko dla kolekcji, ale również dla +        // wszystkich nie-finalnych klas. + +    } // Koniec metody main +} // Koniec klasy LearnJava + +// Możesz zawrzeć inne, niepubliczne, zewnętrzne klasy w pliku .java, +// jednak nie jest to zalecane. Zalecane jest dzielenie klas na osobne pliki. + +// Składnia deklaracji klasy: +// <public/private/protected> class <nazwa klasy> { +//    // pola danych, konstruktory, funkcje. +//    // w jężyku Java funkcje są wywoływane jako metody. +// } + +class Rower { + +    // Zmienne klasy +    public int pedalowanie; // Public: Dostępne wszędzie +    private int predkosc;  // Private: Dostępne tylko w klasie +    protected int przerzutka; // Protected: Dostępne w klasie i podklasach +    String nazwa; // domyślnie: Dostępne tlyko w danej paczce +    static String nazwaKlasy; // Zmienna statyczna + +    // Blok statyczny +    // Java nie posiada implemntacji konstruktorów staycznych, ale +    // posiada blok stayczny, który może  być użyty aby zainicjalizować +    // statyczne zmienne klasy +    // Ten blok będzie wywołane gdy klasa jest ładowana. +    static { +        nazwaKlasy = "Rower"; +    } + +    // Konstruktory służą do stworzenia instancji klas +    // Too jest konstruktor +    public Rower() { +        // Możesz wywołać także  inny konstruktor: +        // this(1, 50, 5, "Bontrager"); +        przerzutka = 1; +        pedalowanie = 50; +        predkosc = 5; +        nazwa = "Bontrager"; +    } +    // To jest konstruktor, który przyjmuje argumenty +        public Rower(int poczatkowePedalowanie, int poczatkowaPredkosc, int początkowaPrzerzutka, +        String nazwa) { +        this.przerzutka = początkowaPrzerzutka; +        this.pedalowanie = poczatkowePedalowanie; +        this.predkosc = poczatkowaPredkosc; +        this.nazwa = nazwa; +    } + +    // Składnia metod: +    // <public/private/protected> <zwracany rodzaj> <nazwa funkcji>(<argumenty>) + +    // Klasy często implementują metody getter i setter dla danych wewnątrz + +    // Składnia deklaracji metody: +    // <dostępność> <zwracany rodzaj> <nawa metody>(<argumenty>) +    public int getPedalowanie() { +        return pedalowanie; +    } + +    // metody void nie wymagają słowa kluczowego return, nic nie zwracają +    public void setPedalowanie(int newValue) { +        pedalowanie = newValue; +    } +    public void setPrzerzutka(int newValue) { +        przerzutka = newValue; +    } +    public void predkoscZwieksz(int inkrement) { +        predkosc += inkrement; +    } +    public void predkoscZmniejsz(int dekrement) { +        predkosc -= dekrement; +    } +    public void nadajNazwe(String nowaNazwa) { +        nazwa = nowaNazwa; +    } +    public String zwrocNazwe() { +        return nazwa; +    } + +    // Metoda do wyświetlenia wartości atrybutów danego obiektu. +    @Override // Dziedziczy z klasy obiektu. +    public String toString() { +        return "przerzutka: " + przerzutka + " pedalowanie: " + pedalowanie + " predkosc: " + predkosc + +            " nazwa: " + nazwa; +    } +} // koniec klasy Rower + +// PennyFarthing jest podklasą klasy Rower +class PennyFarthing extends Rower { +    // (Penny Farthing to rower z wielkim przednim kołem. +    // Nie ma przerzutek.) + +    public PennyFarthing(int poczatkowePedalowanie, int poczatkowaPredkosc) { +        // Wywołanie kostruktora klasy z której dziedziczymy za pomocą super +        super(poczatkowePedalowanie, poczatkowaPredkosc, 0, "PennyFarthing"); +    } + +    // Używamy annotacji @annotation przy przeciążaniu metod. +    // Aby dowiedzieć się więcej o annotacjach przydatne jest przejrzenie +    // (w języku angielskim): +    // http://docs.oracle.com/javase/tutorial/java/annotations/ +    @Override +    public void setPrzerzutka(int przerzutka) { +        this.przerzutka = 0; +    } +} + +// Rzutowanie +// Jako, że  klasa PennyFarthing dziedziczy z klasy Rower, możemy uznać, że +// instancja PennyFarthing jest typu Rower i napisać : +// Rower rower = new PennyFarthing(); +// Dana operacja jest rzutowaniem obiektu, gdzie jego domyślna klasa jest inna niż docelowa. +// Więcej szczegółów i przykładów oraz ciekawych konceptów (po angielsku): +// https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html + +// Interfejsy +// Składnia deklaracji interfejsu +// <dostępność> interface <nazwa interfejsu> extends <super-interfaces> { +//     // Zmienne typu constant +//     // Deklaracje metod +// } + +// Przykład - Jedzenie: +public interface Jadalne { +    public void jedz(); // Każda klasa która implemetuje ten interfejs musi +    // implementować tę metodę. +} + +public interface Przetrawialne { +    public void przetrawiaj(); +    // Wraz z Java 8, interfejsy mogą mieć metodę domyślną. +    public default void defaultMethod() { +        System.out.println("Hej z metody domyślnej ..."); +    } +} + +// Teraz stworzymy klasę, która zaimplementuje oba interfejsy. +public class Owoc implements Jadalne, Przetrawialne { +    @Override +    public void jedz() { +        // ... +    } + +    @Override +    public void przetrawiaj() { +        // ... +    } +} + +// W Javie możesz dziedziczyć jedynie z jednej klasy, jednak implementować +// wiele interfejsów. Na przykład: +public class Przyklad extends Przodek implements Interfejs1, +    Interfejs2 { +    @Override +    public void Interfejs1Metoda() { +    } + +    @Override +    public void Interfejs2Metoda() { +    } + +} + +// Klasy abstrakcyjne + +// Składnia deklaracji klasy abstrakcyjnej +// <dostępność> abstract class <nawa klasy abstrakcyjnej> extends +// <superklasy, z których dziedziczy> { +//     // Zmienne i stałe +//     // Deklaracje metod +// } + +// Klasy abstrakcyjne nie mogą posiadać instancji. +// Klasy abstrakcyjne mogą definiować  metody abstrakcyjne. +// Metody abstrakcyjne nie mają ciała funkcji i są oznaczone jako abstrakcyjne. +// Nieabstrakcyjne klasy-dzieci muszą przeciążać wszystkie abstrakcyjne metody +// superklasy. +// Klasy abstrakcyjne są użyteczne gdy wymagana jest powtarzalna logika działania, +// jednak należy zaauważyć, że jako, że wymagają dziedziczenia, łamią +// zasadę "Composition over inheritance". Rozważ inne podejścia używając +// kompozycji. https://en.wikipedia.org/wiki/Composition_over_inheritance + +public abstract class Zwierze +{ +    private int wiek; + +    public abstract void dajGlos(); + +    // Metody mogą mieć ciało +    public void jedz() +    { +        System.out.println("Jestem zwierzeciem i jem."); +        // Uwaga: Możliwy jest dostęp do zmiennych prywatnych. +        wiek = 30; +    } + +    public void wyswietlWiek() +    { +        System.out.println(wiek); +    } + +    // Klasy abstrakcyjne mogą mieć metodę główną. +    public static void main(String[] args) +    { +        System.out.println("Jestem abstrakcyjna"); +    } +} + +class Pies extends Zwierze +{ +    // Musimy przeciążyć wszystkie abstrakcyjne metody z klasy abstrakcyjnej +    @Override +    public void dajGlos() +    { +        System.out.println("Hau"); +        // wiek = 30;    ==> BLAD!    wiek jest typu private dla Zwierze +    } + +    // NOTE: Wystąpi błąd jeżeli użyto annotacji @Override jako, że Java +    // nie pozwala na przeciążanie metod statycznych. +    // Występuje tutaj METHOD HIDING - ukrywanie metod. +    // Więcej w poście na SO: http://stackoverflow.com/questions/16313649/ +    public static void main(String[] args) +    { +        Pies pluto = new Pies(); +        pluto.dajGLos(); +        pluto.jedz(); +        pluto.wyswietlWiek(); +    } +} + +// Klasy finalne + +// Składnia deklaracji klasy finalnej +// <dostępność> final <nazwa klasy finalnej> { +//     // Zmienne i stałe +//     // Deklaracje Metody +// } + +// Klasy finalne są klasami, które nie mogą być użyte do dziedziczenia, są więc +// z założenia ostatnim elementem dziedziczenia. W ten sposób są przeciwnością +// klas abstrakcyjnych, które z założenia muszą być dziedziczone. +public final class TygrysSzablozebny extends Zwierze +{ +    // Nadal musimy przeciążyć metody abstrakcyjne klasy abstrakcyjnej Zwierze +    @Override +    public void dajGlos() +    { +        System.out.println("Roar"); +    } +} + +// Metody finalne +public abstract class Ssak +{ +    // Składnia metody finalnej: +    // <dostępność> final <zwracany rodzaj> <nazwa funkcji>(<argumenty>) + +    // Metody finalne, jak klasy finalne nie mogą być przeciążane +    // i są w ten sposób ostatecznymi implementacjami danej metody. +    public final boolean jestStalocieplny() +    { +        return true; +    } +} + +// Enumeratory +// +// Enumerator jest specjalnym tyme danej, która pozwala zmiennej na bycie +// zestawem wcześniej zdefiniowanych stałych. Zmienna musi być równa jednej z +// wartości wcześniej zdefiniowanych. Jako, że są to stałe, nazwy pól typu enum +// są pisane wielkimi literami. W języku Java typ enum definiujemy przez użycie +// słowa enum. Na przykład aby zdefiniować dni tygodnia: +public enum Dzien { +    PONIEDZIALEK, WTOREK, SRODA, CZWARTEK, +    PIATEK, SOBOTA, NIEDZIELA +} + +// We can use our enum Day like that: +public class EnumTest { +    // Zmienna typu enum +    Dzien dzien; + +    public EnumTest(Dzien dzien) { +        this.dzien = dzien; +    } + +    public void opiszDzien() { +        switch (dzien) { +            case PONIEDZIALEK: +                System.out.println("Nie lubię poniedziałku!"); +                break; +            case PIATEK: +                System.out.println("Piątki są dużo lepsze."); +                break; +            case SOBOTA: +            case NIEDZIELA: +                System.out.println("Weekendy są najlepsze."); +                break; +            default: +                System.out.println("Środek tygodnia jest taki sobie."); +                break; +        } +    } + +    public static void main(String[] args) { +        EnumTest pierwszyDzien = new EnumTest(Dzien.PONIEDZIALEK); +        pierwszyDzien.opiszDzien(); // => Nie lubię poniedziałku! +        EnumTest trzeciDzien = new EnumTest(Dzien.SRODA); +        trzeciDzien.opiszDzien(); // => Środek tygodnia jest taki sobie. +    } +} + +// Typ enum jest bardziej wszechstronny niż powyższa demostracja. +// Ciało typu enum może zawierać metody i inne pola. +// Rzuć okiem na (angielski) https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html + +// Wprowadzenie do wyrażeń lambda +// +// Nowe w Javie 8 są wyrażenia lambda. Lambdy znajdujemy zwykle w funkcyjnych +// językach programowania, co oznacza, że są metodami, które potrafią być +// stowrzone bez klasy i przekazywane jak gdyby były obiektem oraz wykonywane +// gdy zajdzie potrzeba. +// +// Ostatnia uwaga - lambdy muszą implementować funcjonalny interfejs. +// Interfels funkcjonalny to taki, który ma jedynie jedną zadeklarowaną metodę +// abstrakcyjną, ale może mieć dowolną ilość domyślnych metod. Wyrażenia lambda +// mogą być używane jako instancje tego interfejsu. Każdy inteferjs, który +// spełnia wymagania jest traktowany jako funkcjonalny. Więcej o interfejsach +// znajdziesz powyżej, w odpowiedniej sekcji. +// +import java.util.Map; +import java.util.HashMap; +import java.util.function.*; +import java.security.SecureRandom; + +public class Lambdas { +    public static void main(String[] args) { +        // Składnia deklaracji lambdy: +	    // <zero lub więcej parametrów> -> <ciało wyrażenia lub blok instrukcji> + +        // Poniżej w przykładzie użyjemy tablicy z hashowaniem. +        Map<String, String> planety = new HashMap<>(); +            planety.put("Merkury", "87.969"); +            planety.put("Wenus", "224.7"); +            planety.put("Ziemia", "365.2564"); +            planety.put("Mars", "687"); +            planety.put("Jowisz", "4,332.59"); +            planety.put("Saturn", "10,759"); +            planety.put("Uran", "30,688.5"); +            planety.put("Neptun", "60,182"); + +        // Lambda z zerową liczbą parametrów używając funkcjonalnego interfejsu +        // Supplier z java.util.function.Supplier. Faktyczną lambdą jest częśc +        // po numPlanets =. +        Supplier<String> numPlanety = () -> Integer.toString(planety.size()); +        System.out.format("Liczba planet: %s\n\n", numPlanety.get()); + +        // Lambda z jednym parametrem używająca funkcjonalnego interfejsu +        // Consumer z java.util.function.Consumer.planety jest mapą, która +        // wimplementuje Collection jak i Iterable. Użyty forEach pochodzi z +        // Iterable i jest użyty w lambdzie na każdym elemencie kolekcji +        // Domyślna implementacja forEach wygląda tak: +        /* +            for (T t : this) +                action.accept(t); +        */ + +        // Faktyczna lambda jest parametrem przekazywanym do forEach. +        planety.keySet().forEach((p) -> System.out.format("%s\n", p)); + +        // Jeżeli przekazujemy tyklo pojedynczy argumentpowyższy zapis możemy +        // przekształcić do (zauważ brak nawiasów dookoła p): +        planety.keySet().forEach(p -> System.out.format("%s\n", p)); + +        // Śledząc powyższe widzimy, że planety jest typu HashMap, a keySet() +        // zwraca zestaw kluczy, forEach stosuje o każdego elementu lambdę: +        // (parameter p) -> System.out.format("%s\n", p). Za każdym razem +        // element jest uznawany jako  "konsumowany" i wyrażenie (wyrażenia) +        // w lambdzie są wykonywane. Pamiętaj, że ciało lambdy to część po +        // symbolu ->. + +        // Powyższy przykład bez użycia lambdy wyglądałby tradycyjnie tak: +        for (String planeta : planety.keySet()) { +            System.out.format("%s\n", planeta); +        } + +        // Poniższy przykład różni się od powyższego sposobem implementacji +        // forEach:  forEach użyty w klasie HashMap implementuje intefejs Map. +        // Poniższy forEach przyjmuje BiConsumer, który ogólnie ujmując jest +        // wymyślnym sposobem stwierdzenia, że zajmuje się zestawem par +        // klucz-wartość Key -> Value dla każdego klucza. Ta domyślna +        // implementacja działa jak: +        /* +            for (Map.Entry<K, V> entry : map.entrySet()) +                action.accept(entry.getKey(), entry.getValue()); +        */ + +        // Faktyczna lambda jest parametrem przekazywanym do forEach. +        String orbity = "%s okrąża Słońce w %s dni.\n"; +        planety.forEach((K, V) -> System.out.format(orbity, K, V)); + +        // Powyższe bez użycia lambdy wyglądałoby tradycyjnie tak: +        for (String planet : planety.keySet()) { +            System.out.format(orbity, planet, planety.get(planet)); +        } + +        // Lub jeżeli postępujemy zgodnie ze specyfikacją domyślnej implementacji: +        for (Map.Entry<String, String> planeta : planety.entrySet()) { +            System.out.format(orbity, planeta.getKey(), planeta.getValue()); +        } + +        // Podane przykłady pokrywają jedynie podstawowe zastosowanie wyrażeń +        // lambda. Być może wydają się one niezbyt przydatne, jednak należy +        // pamiętać, że lambdy można stworzyć jako obiekty, które nastepnie mogą +        // zostać przekazane jako parametry do innych metod. +    } +} +``` + +## Dalsze materiały + +Linki zamieszczone poniżej służą pomocą w zrozumieniu wybranego tematu, w razie braku rozwiązania wyszukanie w Google zwykle służy pomocą + +**Oficjalne poradniki Oracle po angielsku**: + +* [Tutorial w Javie od Sun / Oracle](https://docs.oracle.com/javase/tutorial/index.html) + +* [Modyfikacje poziomu dostępu w Java](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) + +* [Koncepty programowania obiektowego](https://docs.oracle.com/javase/tutorial/java/concepts/index.html): +    * [Dziedziczenie](https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html) +    * [Polimorfizm](https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html) +    * [Abstrakcja](https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html) + +* [Wyjątki](https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html) + +* [Interfejsy](https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html) + +* [Uogólnianie](https://docs.oracle.com/javase/tutorial/java/generics/index.html) + +* [Konwencja kodu Java](https://www.oracle.com/technetwork/java/codeconvtoc-136057.html) + +* Nowości z Java 8: +    * [Funkcje Lambda (programowanie funkcyjne)](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html) +    * [Data y czas API (java.time package)](http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html) + +**Kursy po polsku** + +* [PJWSTK - Podstawy programowania w języku Java](http://edu.pjwstk.edu.pl/wyklady/ppj/scb/) + +* [PJWSTK - Programowanie obiektowe w języku Java](http://edu.pjwstk.edu.pl/wyklady/poj/scb/) + +**Tutoriale i ćwiczenia online po angielsku** + +* [Learneroo.com - Learn Java](http://www.learneroo.com) + +* [Codingbat.com](http://codingbat.com/java) + +* [Codewars - Java Katas](https://www.codewars.com/?language=java) + +**Książki po angielsku**: + +* [Head First Java](http://www.headfirstlabs.com/books/hfjava/) + +* [Thinking in Java](http://www.mindview.net/Books/TIJ/) + +* [Objects First with Java](https://www.amazon.com/Objects-First-Java-Practical-Introduction/dp/0132492660) + +* [Java The Complete Reference](https://www.amazon.com/gp/product/0071606300) diff --git a/ru-ru/learnvisualbasic-ru.html.markdown b/ru-ru/learnvisualbasic-ru.html.markdown new file mode 100644 index 00000000..72e1358c --- /dev/null +++ b/ru-ru/learnvisualbasic-ru.html.markdown @@ -0,0 +1,284 @@ +--- +language: Visual Basic +contributors: +    - ["Brian Martin", "http://brianmartin.biz"] +translators: +    - ["satory-ra", "https://github.com/satory-ra"] +filename: learnvisualbasic-ru.vb +lang: ru-ru +--- + +```vbnet +Module Module1 + +    Sub Main() +        'Краткий обзор консольных приложений Visual Basic перед более +        'глубоким изучением. +        'Апостроф начинает строку комментария. +        'Чтобы изучить это руководство в компиляторе Visual Basic, +        'я создал систему навигации. +        'Эта система будет объяснена при прохождении этого урока. +        'Постепенно вы всё поймете. +        Console.Title = ("Выучи Х за Y минут") +        Console.WriteLine("НАВИГАЦИЯ") 'Display +        Console.WriteLine("") +        Console.ForegroundColor = ConsoleColor.Green +        Console.WriteLine("1. Вывод данных") +        Console.WriteLine("2. Ввод данных") +        Console.WriteLine("3. Расчёт целых чисел") +        Console.WriteLine("4. Расчёт десятичных дробей") +        Console.WriteLine("5. Калькулятор") +        Console.WriteLine("6. Использование циклов Do While") +        Console.WriteLine("7. Использование циклов For") +        Console.WriteLine("8. Условные выражения") +        Console.WriteLine("9. Выберите напиток") +        Console.WriteLine("50. О приложении") +        Console.WriteLine("Выберите номер из списка") +        Dim selection As String = Console.ReadLine +        '«Case» в операторе Select не является обязательным. +        'Например, "Select selection" вместо "Select Case selection" +        'также будет работать. +        Select Case selection +            Case "1" 'Вывод данных +                Console.Clear() 'Очищает окно консоли +                HelloWorldOutput() 'Открывает приватную подпрограмму. +            Case "2" 'Ввод данных +                Console.Clear() +                HelloWorldInput() +            Case "3" 'Расчёт целых чисел +                Console.Clear() +                CalculatingWholeNumbers() +            Case "4" 'Расчёт десятичных дробей +                Console.Clear() +                CalculatingDecimalNumbers() +            Case "5" 'Калькулятор +                Console.Clear() +                WorkingCalculator() +            Case "6" 'Использование циклов Do While +                Console.Clear() +                UsingDoWhileLoops() +            Case "7" 'Использование циклов For +                Console.Clear() +                UsingForLoops() +            Case "8" 'Условные выражения +                Console.Clear() +                ConditionalStatement() +            Case "9" 'Выражения If/Else +                Console.Clear() +                IfElseStatement() 'Выберите напиток +            Case "50" 'Окно сообщения «О приложении» +                Console.Clear() +                Console.Title = ("Выучи Х за Y минут :: О приложении") +                MsgBox("Это руководство от Брайана Мартина (@BrianMartinn") +                Console.Clear() +                Main() +                Console.ReadLine() + +        End Select +    End Sub + +    'Один - Я использую эти цифры для того, чтобы было проще +    'соотносить код с системой навигации. + +    'Мы используем частные подпрограммы для разделения различных +    'разделов программы. +    Private Sub HelloWorldOutput() +        'Название консольного приложения +        Console.Title = "Вывод данных | Выучи Х за Y минут" +        'Используйте Console.Write ("") или Console.WriteLine ("") +        'для отображения результатов. +        'Затем следует Console.Read () или Console.Readline () +        'Console.ReadLine () показывает вывод в консоли. +        Console.WriteLine("Hello World") +        Console.ReadLine() +    End Sub + +    'Два +    Private Sub HelloWorldInput() +        Console.Title = "Ввод данных | Выучи Х за Y минут" +        'Переменная +        'используется для хранения пользовательских данных. +        'Объявление переменных начинается с Dim и заканчиваются +        'As VariableType (тип переменной). + +        'В этом уроке мы хотим узнать ваше имя и заставить программу  +        'реагировать на это. +        Dim username As String +        'Мы используем тип «string», так как ваше имя - это текстовая переменная. +        Console.WriteLine("Привет, как тебя зовут? ") 'Просит ввести имя. +        username = Console.ReadLine() 'Сохраняет имя в переменной username. +        Console.WriteLine("Пирвет, " + username) 'Выводит: «Привет, 'имя'» +        Console.ReadLine() 'Отображает вышеуказанный вывод. + +        'Вышеуказанная программа спросит ваше имя и скажет вам привет. +        'Есть и другие типы переменных, такие как целые числа (Integer), +        'мы используем Integer для обработки целых чисел. +    End Sub + +    'Три +    Private Sub CalculatingWholeNumbers() +        Console.Title = "Расчёт целых чисел | Выучи Х за Y минут" +        Console.Write("Первое число: ") 'Введите первое целое число: 1, 2, 50, 104 и т.д. +        Dim a As Integer = Console.ReadLine() +        Console.Write("Второе число: ") 'Введите второе целое число. +        Dim b As Integer = Console.ReadLine() +        Dim c As Integer = a + b +        Console.WriteLine(c) +        Console.ReadLine() +        'Приведенная программа сумирует два целых числа +    End Sub + +    'Четыре +    Private Sub CalculatingDecimalNumbers() +        Console.Title = "Расчёт десятичных дробей | Выучи Х за Y минут" +        'Мы также должны уметь обрабатывать десятичные дроби. +        'Просто измените тип переменной с Integer на Double. + +        'Введите число с плавающей точкой: 1.2, 2.4, 50.1, 104.9 и т.д. +        Console.Write("Первое число: ") +        Dim a As Double = Console.ReadLine +        Console.Write("Второе число: ") 'Введите второе число с плавающей точкой. +        Dim b As Double = Console.ReadLine +        Dim c As Double = a + b +        Console.WriteLine(c) +        Console.ReadLine() +        'Приведенный выше код может сложить две десятичных дроби. +    End Sub + +    'Пять +    Private Sub WorkingCalculator() +        Console.Title = "Калькулятор | Выучи Х за Y минут" +        'Но что, если вам нужен калькулятор, который может обрабатывать сложение,  +        'вычитание, умножение и деление? +        'Просто скопируйте и вставьте приведенный код. +        Console.Write("Первое число: ") +        Dim a As Double = Console.ReadLine +        Console.Write("Второе число: ") +        Dim b As Double = Console.ReadLine +        Dim c As Double = a + b +        Dim d As Double = a * b +        Dim e As Double = a - b +        Dim f As Double = a / b + +        'С помощью следующего кода мы можем вывести результат сложения, +        'вычитания, умножения и деления, рассчитанный выше, на экран. +        Console.Write(a.ToString() + " + " + b.ToString()) +        'Мы хотим, чтобы в начале ответа было 3 пробела, для этого  +        'вы можете использовать метод String.PadLeft (3). +        Console.WriteLine(" = " + c.ToString.PadLeft(3)) +        Console.Write(a.ToString() + " * " + b.ToString()) +        Console.WriteLine(" = " + d.ToString.PadLeft(3)) +        Console.Write(a.ToString() + " - " + b.ToString()) +        Console.WriteLine(" = " + e.ToString.PadLeft(3)) +        Console.Write(a.ToString() + " / " + b.ToString()) +        Console.WriteLine(" = " + f.ToString.PadLeft(3)) +        Console.ReadLine() + +    End Sub + +    'Шесть +    Private Sub UsingDoWhileLoops() +        'Код такой же, как и в предидущей подпрограмме +        'На этот раз мы спрашиваем, хочет ли пользователь продолжить (да или нет?) +        'Мы будем использовать цикл Do While, потому что не знаем, +        'понадобиться ли пользователю калькулятор болше одного раза. +        Console.Title = "Использование циклов Do While | Выучи Х за Y минут" +        Dim answer As String +        'Мы используем тип переменной "String", так как её значение текст. +        Do 'Мы начаем программу с +            Console.Write("Первое число: ") +            Dim a As Double = Console.ReadLine +            Console.Write("Второе число: ") +            Dim b As Double = Console.ReadLine +            Dim c As Double = a + b +            Dim d As Double = a * b +            Dim e As Double = a - b +            Dim f As Double = a / b + +            Console.Write(a.ToString() + " + " + b.ToString()) +            Console.WriteLine(" = " + c.ToString.PadLeft(3)) +            Console.Write(a.ToString() + " * " + b.ToString()) +            Console.WriteLine(" = " + d.ToString.PadLeft(3)) +            Console.Write(a.ToString() + " - " + b.ToString()) +            Console.WriteLine(" = " + e.ToString.PadLeft(3)) +            Console.Write(a.ToString() + " / " + b.ToString()) +            Console.WriteLine(" = " + f.ToString.PadLeft(3)) +            Console.ReadLine() +            'Спросите пользователя, хочет ли он продолжить, +            'в ответе учитывается регистр букв. +            Console.Write("Желаете ли вы продолжить? (да / нет)") +            'Программа берет значение и записывает в переменную answer. +            answer = Console.ReadLine() +            'Когда пользователь вводит «да», программа переходит к Do и снова запускается. +        Loop While answer = "yes" + +    End Sub + +    'Семь +    Private Sub UsingForLoops() +        'Иногда программу нужно запускать только один раз. +        'В этой программе мы осуществим обратный отсчет от 10. + +        Console.Title = "Использование циклов For | Выучи Х за Y минут" +        'Объявите переменные и Step (размер шага, то есть скорость уменьшения, +        'например, -1, -2, -3 и т.д.). +        For i As Integer = 10 To 0 Step -1 +            Console.WriteLine(i.ToString) 'Показывает значение счетчика. +        Next i 'Рассчитать новое значение i. +        Console.WriteLine("Поехали") +        Console.ReadLine() +    End Sub + +    'Восемь +    Private Sub ConditionalStatement() +        Console.Title = "Условные выражения | Выучи Х за Y минут" +        Dim userName As String +        Console.WriteLine("Привет, как тебя зовут? ") 'Спросите имя пользователя. +        userName = Console.ReadLine() 'Записать имя в переменную userName. +        If userName = "Адам" Then +            Console.WriteLine("Привет, Адам") +            Console.WriteLine("Спасибо за создание этого полезного сайта") +            Console.ReadLine() +        Else +            Console.WriteLine("Привет " + userName) +            Console.WriteLine("Вы заглянули на сайт www.learnxinyminutes.com") +            Console.ReadLine() 'Программа останавливается и выводит вышеуказанный текст. +        End If +    End Sub + +    'Девять +    Private Sub IfElseStatement() +        Console.Title = "Выражения If/Else | Выучи Х за Y минут" +        'Иногда важно рассмотреть более двух альтернатив. +        'Иногда некоторые из них лучше других. +        'Когда это произойдет, нам потребуется более одного утверждения «if» (если). +        'Оператор «if» подобен торговому автомату. +        'В котором пользователь пишет код (A1, A2, A3 и т.д.), чтобы выбрать элементы. +        'Все варианты могут быть объединены в одном утверждении «if». + +        Dim selection As String 'Объявить переменную для выбора +        Console.WriteLine("Пожалуйста, выберите продукт из нашего прекрасного торгового автомата.") +        Console.WriteLine("A1. для 7Up") +        Console.WriteLine("A2. для Fanta") +        Console.WriteLine("A3. для Dr. Pepper") +        Console.WriteLine("A4. для Diet Coke") + +        selection = Console.ReadLine() 'Сохранить выбор пользователя +        If selection = "A1" Then +            Console.WriteLine("7up") +        ElseIf selection = "A2" Then +            Console.WriteLine("Fanta") +        ElseIf selection = "A3" Then +            Console.WriteLine("Dr. Pepper") +        ElseIf selection = "A4" Then +            Console.WriteLine("Diet Coke") +        Else +            Console.WriteLine("Извините, у меня нет " + selection) +        End If +        Console.ReadLine() + +    End Sub + +End Module + +``` diff --git a/standard-ml.html.markdown b/standard-ml.html.markdown index b34f1c08..0ba42f39 100644 --- a/standard-ml.html.markdown +++ b/standard-ml.html.markdown @@ -272,6 +272,9 @@ fun evenly_positioned_elems (odd::even::xs) = even::evenly_positioned_elems xs  datatype temp =        C of real      | F of real +     +(*  Declaring a new C temp value... +    val t: temp = C 45.0  *)  fun temp_to_f t =      case t of diff --git a/visualbasic.html.markdown b/visualbasic.html.markdown index 63f224b7..221c1eb3 100644 --- a/visualbasic.html.markdown +++ b/visualbasic.html.markdown @@ -139,7 +139,7 @@ Module Module1      'Five      Private Sub WorkingCalculator() -        Console.Title = "The Working Calculator| Learn X in Y Minutes" +        Console.Title = "The Working Calculator | Learn X in Y Minutes"          'However if you'd like the calculator to subtract, divide, multiple and          'add up.          'Copy and paste the above again. diff --git a/vyper.html.markdown b/vyper.html.markdown new file mode 100644 index 00000000..2c654797 --- /dev/null +++ b/vyper.html.markdown @@ -0,0 +1,867 @@ +--- +language: Vyper +filename: learnVyper.vy +contributors: +  - ["Kenny Peluso", "kennyp.herokuapp.com"] +--- + +> The content of this document is largely inspired by ["Learn Solidity in Y Minutes"](https:#github.com/adambard/learnxinyminutes-docs/blob/master/solidity.html.markdown) + +Vyper lets you program on [Ethereum](https:#www.ethereum.org/), a +blockchain-based virtual machine that allows the creation and +execution of smart contracts, without requiring centralized or trusted parties. It was +designed to improve upon Solidity, another smart contract language for Ethereum, by +limiting unsafe practices and enhancing readability; Vyper seeks to optimize the +security and auditability of smart contracts. + +Vyper is an experimental, statically typed, contract programming language meant to +resemble Python. Like objects in OOP, each contract contains state variables, functions, +and common data types. Contract-specific features include event notifiers for listeners, +and custom global variables, global constants. + +Some Ethereum contract examples include crowdfunding, voting, and blind auctions. + +--- + +## Table of Contents + +- Intro +- Example +1. Data types and associated methods +2. Data structures +3. Simple operators +4. Global variables of note +5. Functions and more +    a. functions +    b. events +6. Branching and loops +7. Objects/contracts +    a. calling external contracts +    b. ERC20 built-in +    c. following an interface +8. Other keywords +    a. selfdestruct +9. Contract design notes +    a. obfuscation +    b. storage optimization +    c. data access in blockchain +    d. cron job +    e. observer pattern +10. Security +11. Style notes +12. Natspec comments +- Other documents + +--- + +## Intro + +From [the docs](https://media.readthedocs.org/pdf/vyper/latest/vyper.pdf) +the foundational tenants of Vyper are: + +1. *Security* +2. *Language and compiler simplicity* +3. *Auditability* + +This allows for the following features: + +1. *Bounds and overflow checking* +   - On the arithmetic and array level +   - There are no dynamic arrays in Vyper +2. *Support for signed integers and decimal fixed point numbers* +3. *Decidability* - You can always compute precise upper bound on gas cost +4. *Strong typing* - for built-in and custom types +5. *Small and understandable compiler code* +6. *Limited support for pure functions* +    - Anything marked `@constant` is not allowed to change the state + +Following the principles and goals, Vyper does not provide the following features: + +1. *Modifiers* (defining parts of functions elsewhere) +2. *Class inheritance* +3. *Inline assembly* +4. *Function overloading* +5. *Operator overloading* +6. *Recursive calling* +7. *Infinite-length loops* +8. *Binary fixed point* (decimal fixed point is used for its exactness) + +WITH THE RAPID CHANGES IN ETHEREUM, THIS DOCUMENT IS UNLIKELY TO STAY UP TO +DATE, SO YOU SHOULD FOLLOW THE LATEST VYPER DOCS AND ETHEREUM BLOG FOR THE LATEST. +ALL CODE HERE IS PROVIDED AS IS, WITH SUBSTANTIAL RISK OF ERRORS OR DEPRECATED CODE +PATTERNS. + +This document primarily discusses syntax, and so excludes many +popular design patterns. + +As Vyper and Ethereum are under active development, experimental or beta +features are typically marked, and subject to change. Pull requests welcome. + +This document describes Vyper version `0.1.0-beta.8`. + +*All of the following code exists for educational purposes only!* +*None of the following code should be used in production as-is!* + +## Example + +```python +# First, a simple todo list contract +# Implements CRUD operations for tasks + +# todo.vy (note .vy extension) +### **** START EXAMPLE **** ### + +# Start with Natspec comment +# used for documentation + +# @title SimpleBank v1 +# @author kennyp +# @notice This is a simple bank. + +# Vyper contracts must obey a particular order: +#   struct -> interface -> events -> globals and constants -> functions +# Additionally, like Python, Vyper functions must be defined in the file +#    before they're called. + +# Structs + +struct Task: +    done: bool +    deleted: bool +    task: string[100] +    metadata: bytes32 + +# Interfaces + +contract AnotherContract(): +    def fetch() -> bytes32: constant +    def inform(_taskId: uint256, _status: uint256) -> bool: modifying + +# Events + +# Events - publicize actions to external listeners +# `indexed` means that it's easier to search/filter on this field +TaskStatus: event({_taskId: indexed(uint256), _status: uint256}) + +# Global Variables + +# State variables are values which are permanently stored in contract storage +# State vars consist of any value persisting beyond any function's scope +#   and are permanently stored in contract storage + +# You can define your own, custom, unmutable constants +CREATED: constant(uint256) = 0 +COMPLETED: constant(uint256) = 1 +DELETED: constant(uint256) = 2 + +# The `public` built-in allows for this address to be read externally +#   without defining a `get()` constant function +owner: public(address) +other: public(address) + +# uint256 means "unsigned positive integer between 0 and 2^256 - 1" +# Overflow protection is built-in to Vyper +taskCount: uint256 +tasks: map(uint256, Task) # dictionary: key=uint256, value: Task struct + +# Private Functions + +# Start each function with Pythonic decorators +# These decorators resemble Natspec but are actually enforced by Vyper's compiler +# These decorators are: +# @public XOR @private (either one or the other) +#   @public (if any contract/user can call it) +#   @private (if only internal functions can call it) +# @payable (if the function is payable i.e. accepting ETH) +# @constant (if the function is not modifying anything on-chain) +@private +def _changeTaskStatus( \ +        _sender: address, \ +        _taskId: uint256, \ +        _status: uint256, \ +    ): +    # backslashes (\) allow for multi-line code +    # Natspec comments are particularly helpful for documentation and readibility +    # Natspec can be included using familiar Pythonic docstring syntax +    """ +    @notice +    @dev `_sender` MUST be `self.owner` +    @param _sender Who is triggering this function +    @param _task The description of the task (only useful when task added) +    """ +    # NOTE: Private functions do not have access to `msg.sender` +    # SIDE NOTE: `msg.sender` refers to whoever immediately called the function of +    #   immediate scope. In other words, if I call a function that calls another +    #   in-contract, public function, then `msg.sender` turns from my address to +    #   the address of the current contract. +    assert _sender == self.owner # failed assertions cause calls/transactions to fail +    # Note that unlike Solidity, `self.` is required to query the contract's state +    # Control flow is Pythonic, as is much of Vyper: +    _task: string[100] # initialized to default value +    _data: bytes32 = sha3(convert(_sender, bytes32)) # owner is obfuscated (but still visible in logs) +    if _status == CREATED: # control flow mimics python +        # How a new struct is instantiated: +        self.tasks[_taskId] = Task({ \ +            done: False, deleted: False, task: _task, metadata: _data \ +        }) +    elif _status == COMPLETED: +        # Modifying an existing struct: +        self.tasks[_taskId].done = True +    elif _status == DELETED: +        self.tasks[_taskId].deleted = True +    AnotherContract(self.other).inform(_taskId, _status) # modifying external call +    log.TaskStatus(_taskId, _status) # emit an event + +# Public Functions + +# Pythonic constructor - can receive none or many arguments +@public +def __init__(_owner: address, _other_contract: address): +    """ +    @dev Called once and only upon contract depoyment +    """ +    self.owner = _owner +    self.other = _other_contract + +# NOTE: Pythonic whitespace rules are mandated in Vyper + +@public +def addTask(_task: string[100]) -> uint256: +    """ +    @notice Adds a task to contract +    @param _task Description of task +    @return Id of newly minted task +    """ +    # msg.sender gives the address of who/what contract is calling this function +    self._changeTaskStatus(msg.sender, self.taskCount, CREATED) +    self.tasks[self.taskCount].task = _task +    self.taskCount += 1 +    return self.taskCount - 1 + +@public +def addSpecialTask(_task: string[100]) -> uint256: +    """ +    @notice Adds a task with metadata pulled from elsewhere +    @param _task Description of task +    @return Id of newly minted task +    """ +    self._changeTaskStatus(msg.sender, self.taskCount, CREATED) +    self.tasks[self.taskCount].task = _task +    self.tasks[self.taskCount].metadata = AnotherContract(self.other).fetch() +    self.taskCount += 1 +    return self.taskCount - 1 + +@public +def completeTask(_taskId: uint256): +    """ +    @notice Marks a task as "completed" +    @param _taskId Id of task to complete +    """ +    self._changeTaskStatus(msg.sender, _taskId, COMPLETED) + +@public +def deleteTask(_taskId: uint256): +    """ +    @notice Adds a task to contract +    @param _taskId Id of task to delete +    """ +    self._changeTaskStatus(msg.sender, _taskId, DELETED) + +@public +@constant # allows function to run locally/off blockchain +def getTask(_taskId: uint256) -> string[100]: +    """ +    @notice Getter for a task's description +    @param _taskId Id of task with desired description +    @return Description of task +    """ +    return self.tasks[_taskId].task + +### **** END EXAMPLE **** ### + + +# Now, the basics of Vyper + + +# --- + + +# 1. DATA TYPES AND ASSOCIATED METHODS +# uint256 used for currency amount and for dates (in unix time) +x: uint256 + +# int of 128 bits, cannot be changed after contract deployment +# with 'constant', compiler replaces each occurrence with actual value +a: constant(int128) = 5 + +# All state variables (those outside a function) +#   are by default 'internal' and accessible inside contract +# Need to explicitly set to 'public' to allow external contracts to access +#   A getter is automatically created, but NOT a setter +# Can only be called in the contract's scope (not within functions) +# Add 'public' field to indicate publicly/externally accessible +a: public(int128) + +# No random functions built in, use other contracts for randomness + +# Type casting is limited but exists +b: int128 = 5 +x: uint256 = convert(b, uint256) + +# Types of accounts: +# Contract Account: f(creator_addr, num_transactions)=address set on contract creation +# External Account: (person/external entity): f(public_key)=address + +# Addresses - An address type can hold an Ethereum address which +#   equates to 20 bytes or 160 bits. It returns in hexadecimal notation +#   with a leading 0x. No arithmetic allowed +owner: public(address) + +# Members can be invoked on all addresses: +owner.balance # returns balance of address as `wei_value` +owner.codesize # returns code size of address as `int128` +owner.is_contract # `True` if Contract Account + +# All addresses can be sent ether via `send()` built-in +@public +@payable +def sendWei(any_addr: address): +    send(any_addr, msg.value) + +# Bytes available +a: bytes[2] +b: bytes[32] +c: bytes32 +# `b` and `c` are 2 different types + +# Bytes are preferable to strings since Vyper currently offers better +#   support for bytes i.e. more built-ins to deal with `bytes32`, `bytes32` +#   can be returned from functions and strings[] can't be, UTF8 (string encoding) +#   uses more storage, etc. + +# There are no dynamically sized bytes, similar to how there are no +#   dynamic arrays + +# Fixed-size byte arrays (Strings) +a: string[100] +b: string[8] +c: string[108] = concat(a, b) # check the latest docs for more built-ins + +# Time +t1: timedelta +t2: timestamp +# Both types are built-in "custom type" variants of `uint256` +# `timedelta` values can be added but not `timestamp` values + +# Money +m: wei_value +# Also has the base type `uint256` like `timestamp` and `timedelta` +# 1 unit of WEI (a small amount of ETH i.e. ether) + +# Custom types +# specify units used in the contract: +units: { +    cm: "centimeter", +    km: "kilometer" +} +# usage: +a: int128(cm) +b: uint256(km) + +# BY DEFAULT: all values are set to 0 on instantiation + +# `clear()` can be called on most types +#   Does NOT destroy value, but sets value to 0, the initial value + + +# --- + + +# 2. DATA STRUCTURES +# Arrays +bytes32[5] nicknames; # static array +bytes32[] names; # dynamic array +uint newLength = names.push("John"); # adding returns new length of the array +# Length +names.length; # get length +names.length = 1; # lengths can be set (for dynamic arrays in storage only) + +# multidimensional fixed array +ls: (uint256[10])[3] # note the parentheses +@public +def setToThree(): +    self.ls[5][3] = 3 # multidimensional array access + +# Dictionaries (any simple type to any other type including structs) +theMap: map(uint256, bytes32) +theMap[5] = sha3("charles") +# theMap[255] result is 0, all non-set key values return zeroes +# To make read public, make a getter that accesses the mapping +@public +def getMap(_idx: uint256) -> bytes32: +    """ +    @notice Get the value of `theMap` at `_idx` +    """ +    return self.theMap[_idx] + +self.getMap(5) # returns sha3("charles") in bytes32 + +# Nested mappings +aMap: map(address, map(address, uint256)) +# NOTE: Mappings are only allowed as state variables +# NOTE: Mappings are not iterable; can only be accessed + +# To delete (reset the mapping's value to default at a key) +clear(balances["John"]) +clear(balances); # sets all elements to 0 + +# Unlike other languages, CANNOT iterate through all elements in +#   mapping, without knowing source keys - can build data structure +#   on top to do this + +# Structs +struct Struct: +    owner: address +    _balance: uint256 # balance is a reserved keyword, is a member for addresses + +exampleStuct: Struct + +@public +def foo() -> uint256: +    self.exampleStuct = Struct({owner: msg.sender, _balance: 5}) +    self.exampleStuct._balance = 10 +    self.exampleStuct._balance = 5 # set to new value +    clear(self.exampleStuct._balance) +    clear(self.exampleStuct) +    return self.exampleStuct._balance + + +# Data locations: Memory vs. storage vs. calldata - all complex types (arrays, +# structs) have a data location +# 'memory' does not persist, 'storage' does +# Default is 'storage' for local and state variables; 'memory' for func params +# stack holds small local variables + +# for most types, can explicitly set which data location to use + + +# --- + + +# 3. SIMPLE OPERATORS +# Comparisons, bit operators and arithmetic operators are provided +# exponentiation: ** +# modulo: % +# maximum: max(x, y) +# AND: bitwise_and(x, y) +# bitwise shift: shift(x, _shift) +#   where x,y are uint256 +#         _shift is int128 + +# 4. GLOBAL VARIABLES OF NOTE +# ** self ** +self # address of contract +# often used at end of contract life to transfer remaining balance to party: +self.balance # balance of current contract +self.someFunction() # calls func externally via call, not via internal jump + +# ** msg - Current message received by the contract ** +# Ethereum programmers take NOTE: this `msg` object is smaller than elsewhere +msg.sender # address of sender +msg.value # amount of ether provided to this contract in wei, the function should be marked `@payable` +msg.gas # remaining gas + +# ** tx - This transaction ** +# Ethereum programmers take NOTE: this `tx` object is smaller than elsewhere +tx.origin # address of sender of the transaction + +# ** block - Information about current block ** +block.timestamp # time at current block (uses Unix time) +# Note that `block.timestamp` can be manipulated by miners, so be careful +block.number # current block number +block.difficulty # current block difficulty + +# ** storage - Persistent storage hash ** +storage['abc'] = 'def'; # maps 256 bit words to 256 bit words + + +# --- + + +# 5. FUNCTIONS AND MORE + +# A. FUNCTIONS +# Simple function +function increment(uint x) returns (uint) { +    x += 1; +    return x; +} + +# Functions can return many arguments +@public +@constant +def increment(x: uint256, y: uint256) -> (uint256, uint256): +    x += 1 +    y += 1 +    return  (x, y) + +# Call previous functon +@public +@constant +def willCall() -> (uint256, uint256): +    return  self.increment(1,1) + +# One should never have to call a function / hold any logic outside +#   outside the scope of a function in Vyper + +# '@constant' +# indicates that function does not/cannot change persistent vars +# Constant function execute locally, not on blockchain +y: uint256 +@public +@constant +def increment(x: uint256) -> uint256: +    x += 1 +    y += 1 # this line would fail +    # y is a state variable => can't be changed in a constant function + + +# 'Function Decorators' +# Used like python decorators but are REQUIRED by Vyper +# @public - visible externally and internally (default for function) +# @private - only visible in the current contract +# @constant - doesn't change state +# @payable - receive ether/ETH +# @nonrentant(<unique_key>) - Function can only be called once, both externally +#                             and internally. Used to prevent reentrancy attacks + +# Functions hare not hoisted +# Functions cannot be assigned to a variable +# Functions cannot be recursive + +# All functions that receive ether must be marked 'payable' +@public +@payable +def depositEther(): +    self.balances[msg.sender] += msg.value + + +# B. EVENTS +# Events are notify external parties; easy to search and +#   access events from outside blockchain (with lightweight clients) +#   typically declare after contract parameters + +# Declare +LogSent: event({_from: indexed(address), address: indexed(_to), _amount: uint256}) +# Call +log.LogSent(from, to, amount) + +/** +For an external party (a contract or external entity), to watch using +the Web3 Javascript library: + +# The following is Javascript code, not Vyper code +Coin.LogSent().watch({}, '', function(error, result) { +    if (!error) { +        console.log("Coin transfer: " + result.args.amount + +            " coins were sent from " + result.args.from + +            " to " + result.args.to + "."); +        console.log("Balances now:\n" + +            "Sender: " + Coin.balances.call(result.args.from) + +            "Receiver: " + Coin.balances.call(result.args.to)); +    } +} +**/ + +# Common paradigm for one contract to depend on another (e.g., a +#   contract that depends on current exchange rate provided by another) + + +# --- + + +# 6. BRANCHING AND LOOPS + +# All basic logic blocks from Python work - including if/elif/else, for, +#   while, break, continue, return - but no switch + +# Syntax same as Python, but no type conversion from non-boolean +# to boolean (comparison operators must be used to get the boolean val) + +# REMEMBER: Vyper does not allow resursive calls or infinite loops + + +# --- + + +# 7. OBJECTS/CONTRACTS +# REMEMBER: Vyper does not allow for inheritance or imports + +# A. CALLING EXTERNAL CONTRACTS +# You must define an interface to an external contract in the current contract + +contract InfoFeed(): +    def getInfo() -> uint256: constant + +info: uint256 + +@public +def __init__(_source: address): +    self.info = InfoFeed(_source).getInfo() + + +# B. ERC20 BUILT-IN +# Using the `ERC20` keyword implies that the contract at the address +#   follows the ERC20 token standard, allowing you to safely call +#   functions like `transfer()`, etc. + +tokenAddress: address(ERC20) + +@public +def transferIt(_to: address, _amt: uint256(wei)): +    self.tokenAddress.transfer(_to, _amt) + + +# C. FOLLOWING AN INTERFACE +# Vyper is experimenting with using the following syntax at the top of +#   a `.vy` file to specify what interfaces are followed by the contract +# This allows interfaces to be better organized, registered, and recognized + +import interfaces.some_interface as SomeInterface +implements: SomeInterface +# <rest of contract> + + +# --- + + +# 8. OTHER KEYWORDS + +# A. selfdestruct() +# selfdestruct current contract, sending funds to address (often creator) +selfdestruct(SOME_ADDRESS); + +# removes storage/code from current/future blocks +# helps thin clients, but previous data persists in blockchain + +# Common pattern, lets owner end the contract and receive remaining funds +@public +def endItAll() { +    assert msg.sender == self.creator # Only let the contract creator do this +    selfdestruct(self.creator) # Makes contract inactive, returns funds + +# May want to deactivate contract manually, rather than selfdestruct +#   (ether sent to selfdestructed contract is lost) + + +# B. sha3() +# Encrypts strings and other data +# Very important on the blockchain +# Takes 1 argument, `concat()` can be called beforehand +# All strings passed are concatenated before hash action +sha3(concat("ab", "cd")) # returns bytes32 + + +# --- + + +# 9. CONTRACT DESIGN NOTES + +# A. Obfuscation +# All variables are publicly viewable on blockchain, so anything +#   that is private needs to be obfuscated (e.g., hashed w/secret) +# Oftentimes, a "commit-reveal" scheme is employed + +# Step 1. Commit +# Place a commitment by sending output of `sha3()` +sha3("a secret"); # btyes32 commit +sha3(concat("secret", "other secret", "salt")); # commit multiple things +# The `sha3()` calculation should occur off-chain, only the bytes32 +#   output should be inputted into some `commit()` function +commits: map(address, bytes32) +@public +def commit(commitment: bytes32): +    self.commits[msg.sender] = commitment + +# Step 2. Reveal +# Send your previously committed data so the contract can check +#   if your commitment was honest +@public +def reveal(_secret: string[100], _salt: string[100]) -> bool: +    return sha3(concat(_secret, _salt)) == self.commits[msg.sender] + + +# B. Storage optimization +# Writing to blockchain can be expensive, as data stored forever; encourages +#   smart ways to use memory (eventually, compilation will be better, but for now +#   benefits to planning data structures - and storing min amount in blockchain) + +# Cost can often be high for items like multidimensional arrays +#   (cost is for storing data - not declaring unfilled variables) + + +# C. Data access in blockchain +# Cannot restrict human or computer from reading contents of +#   transaction or transaction's state + +# While 'private' prevents other *contracts* from reading data +#   directly - any other party can still read data in blockchain + +# All data to start of time is stored in blockchain, so +#   anyone can observe all previous data and changes + + +# D. Cron Job +# Contracts must be manually called to handle time-based scheduling; +#   can create external code to regularly ping or provide incentives +#   (ether) for others to ping + + +# E. Observer Pattern +# An Observer Pattern lets you register as a subscriber and +#   register a function which is called by the oracle (note, the oracle +#   pays for this action to be run) +# Some similarities to subscription in Pub/sub + +# This is an abstract contract, both client and server classes import, +#   the client should implement + +### **** START EXAMPLE **** ### + +contract SomeOracleCallback(): +    def oracleCallback(_value: uint256, _time: timestamp, _info: bytes32): modifying + +MAX_SUBS: constant(uint256) = 100 +numSubs: public(uint256) # number of subscribers +subs: map(uint256, address) # enumerates subscribers + +@public +def addSub(_sub: address) -> uint256: +    """ +    @notice Add subscriber +    @param _sub Address to add +    @return Id of newly added subscriber +    """ +    self.subs[self.numSubs] = _sub +    self.numSubs += 1 +    return self.numSubs - 1 + +@private +def notify(_value: uint256, _time: timestamp, _info: bytes32) -> bool: +    """ +    @notice Notify all subscribers +    @dev Check `numSubs` first; Watch out for gas costs! +    @param _value whatever +    @param _time what have you +    @param _info what else +    @return True upon successful completion +    """ +    j: uint256 +    for i in range(MAX_SUBS): +        j = convert(i, uint256) # `i` is int128 by default +        if j == self.numSubs: +            return True +        SomeOracleCallback(self.subs[j]).oracleCallback(_value, _time, _info) + +@public +def doSomething(): +    """ +    @notice Do something and notify subscribers +    """ +    # ...something... +    whatever: uint256 = 6 +    what_have_you: timestamp +    what_else: bytes32 = sha3("6") +    self.notify(whatever, what_have_you, what_else) + +# Now, your client contract can addSubscriber by importing SomeOracleCallback +# and registering with Some Oracle + +### **** END EXAMPLE **** ### + + +# --- + + +# 10. SECURITY +# Bugs can be disastrous in Ethereum contracts - and even popular patterns in +#   Vyper may be found to be antipatterns + +# See security links at the end of this doc + + +# --- + + +# 11. STYLE NOTES +# Based on Python's PEP8 style guide +# Full Style guide: http:#solidity.readthedocs.io/en/develop/style-guide.html + +# Quick summary: +# 4 spaces for indentation +# Two lines separate contract declarations (and other top level declarations) +# Avoid extraneous spaces in parentheses +# Can omit curly braces for one line statement (if, for, etc) +# else should be placed on own line + +# Specific to Vyper: +# arguments: snake_case +# events, interfaces, structs: PascalCase +# public functions: camelCase +# private functions: _prefaceWithUnderscore + + +# --- + + +# 12. NATSPEC COMMENTS +# used for documentation, commenting, and external UIs + +# Contract natspec - always above contract definition +# @title Contract title +# @author Author name + +# Function natspec +# Should include in docstring of functions in typical Pythonic fashion +# @notice Information about what function does; shown when function to execute +# @dev Function documentation for developer + +# Function parameter/return value natspec +# @param someParam Some description of what the param does +# @return Description of the return value + +``` + +## Additional resources +- [Installation](https://vyper.readthedocs.io/en/latest/installing-vyper.html) +- [Vyper Docs](https://media.readthedocs.org/pdf/vyper/latest/vyper.pdf) +- [Vyper GitHub (under active dev)](https://github.com/ethereum/vyper) +- [Tools and Resources](https://github.com/ethereum/vyper/wiki/Vyper-tools-and-resources) +- [Online Compiler](https://vyper.online/) + +## Sample contracts +- [Uniswap](https://github.com/Uniswap/contracts-vyper) +- [Generalized Governance](https://github.com/kpeluso/gdg) +- [Dynamic Arrays](https://github.com/kpeluso/vyper-dynamic-array) + +## Security +Vyper is secure by design, but it may be helpful to understand what Vyper is +protecting you from. +- [Thinking About Smart Contract Security](https:#blog.ethereum.org/2016/06/19/thinking-smart-contract-security/) +- [Smart Contract Security](https:#blog.ethereum.org/2016/06/10/smart-contract-security/) +- [Hacking Distributed Blog](http:#hackingdistributed.com/) + +## Style +- [Vyper Style Guide WIP](https://github.com/ethereum/vyper/issues/905) +  - Heavily derived from [Solidity's style guide](http:#solidity.readthedocs.io/en/latest/style-guide.html) ... +  - ... which, in turn, is heavily derived from Python's [PEP 8](https:#www.python.org/dev/peps/pep-0008/) style guide. + +## Editors +- [Vyper for VS Code (alpha)](https://github.com/p-/vscode-vyper) + +## Future To Dos +- Update to current Vyper release +- List of common design patterns + +*Feel free to send a pull request with any edits - or email* `pelusoken -/at-/ gmail` + | 
