diff options
27 files changed, 1877 insertions, 192 deletions
diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown index 5fa1d03d..455c3256 100644 --- a/CONTRIBUTING.markdown +++ b/CONTRIBUTING.markdown @@ -71,3 +71,10 @@ contributors: lang: ep-ep --- ``` + +### Should I add myself as a Contributor? + +If you want to add yourself to contributors, keep in mind that contributors get +equal billing, and the first contributor usually wrote the whole article. Please +use your judgement when deciding if your contribution constitutes a substantial +addition or not. diff --git a/c.html.markdown b/c.html.markdown index 87a047be..0c6df413 100644 --- a/c.html.markdown +++ b/c.html.markdown @@ -8,6 +8,7 @@ contributors: - ["Marco Scannadinari", "https://marcoms.github.io"] - ["Zachary Ferguson", "https://github.io/zfergus2"] - ["himanshu", "https://github.com/himanshu81494"] + - ["Joshua Li", "https://github.com/JoshuaRLi"] --- Ah, C. Still **the** language of modern high-performance computing. @@ -19,11 +20,12 @@ memory management and C will take you as far as you need to go. > **About compiler flags** > > By default, gcc and clang are pretty quiet about compilation warnings and -> errors, which can be very useful information. Using some -> stricter compiler flags is recommended. Here is an example you can -> tweak to your liking: +> errors, which can be very useful information. Explicitly using stricter +> compiler flags is recommended. Here are some recommended defaults: > -> `-Wall -Wextra -Werror -O0 -ansi -pedantic -std=c11` +> `-Wall -Wextra -Werror -O2 -std=c99 -pedantic` +> +> For information on what these flags do as well as other flags, consult the man page for your C compiler (e.g. `man 1 gcc`) or just search online. ```c // Single-line comments start with // - only available in C99 and later. diff --git a/crystal.html.markdown b/crystal.html.markdown index 15cbc0b1..8210b443 100644 --- a/crystal.html.markdown +++ b/crystal.html.markdown @@ -301,7 +301,6 @@ end (1..3).each do |index| puts "Index: #{index}" end -# Index: 0 # Index: 1 # Index: 2 # Index: 3 @@ -422,7 +421,7 @@ class Human @name end - # The above functionality can be encapsulated using the attr_accessor method as follows + # The above functionality can be encapsulated using the propery method as follows property :name # Getter/setter methods can also be created individually like this diff --git a/cs-cz/elm.html.markdown b/cs-cz/elm.html.markdown index f19f9e8b..42ec89e5 100644 --- a/cs-cz/elm.html.markdown +++ b/cs-cz/elm.html.markdown @@ -75,8 +75,8 @@ List.head [] -- Nothing -- K získání hodnot z dvojice použijte funkce first a second. -- (Toto je pouze zkratka. Brzy si ukážeme, jak na to "správně".) -fst ("elm", 42) -- "elm" -snd ("elm", 42) -- 42 +Tuple.first ("elm", 42) -- "elm" +Tuple.second ("elm", 42) -- 42 -- Prázná n-tice, neboli "unit", se občas používá jako zástupný symbol. -- Je to jediná hodnota svého typu, který se také nazývá "Unit". diff --git a/de-de/dynamic-programming-de.html.markdown b/de-de/dynamic-programming-de.html.markdown new file mode 100644 index 00000000..801d2514 --- /dev/null +++ b/de-de/dynamic-programming-de.html.markdown @@ -0,0 +1,77 @@ +--- +category: Algorithms & Data Structures +name: Dynamic Programming +contributors: + - ["Akashdeep Goel", "http://github.com/akashdeepgoel"] +translators: + - ["Henrik Jürges", "http://github.com/santifa"] +lang: de-de +--- + +# Dynamische Programmierung + +## Einführung +Dynamische Programmierung ist eine leistungsfähige Technik, die zur Lösung +einer bestimmten Klasse von Problemen verwendet wird. +Die Idee ist sehr einfach, wenn Sie ein Problem mit der gegebenen Eingabe +gelöst haben, dann speichern Sie das Ergebnis für die spätere Referenz, um zu +vermeiden, das gleiche Problem noch einmal zu lösen. + +Denken Sie immer daran! +"Diejenigen, die sich nicht an die Vergangenheit erinnern können, +sind dazu verdammt, sie zu wiederholen." + +## Wege zur Lösung solcher Probleme + +1. *Top-Down*: Lösen Sie das gegebene Problem, indem Sie es aufteilen. +Wenn Sie sehen, dass das Problem bereits gelöst ist, geben Sie einfach die +gespeicherte Antwort zurück. Wenn es nicht gelöst wurde, lösen Sie es und +speichern Sie die Antwort. Dieser Ansatz ist leicht zu verfolgen und sehr +intuitiv. Er wird als Memoization bezeichnet. + +2. *Bottom-Up*: Analysieren Sie das Problem und beobachten Sie, in welcher +Reihenfolge die Teilprobleme gelöst werden können. Beginnen Sie mit der +Lösung vom trivialen Teilproblem bis zum gegebenen Problem. Dabei wird +sichergestellt, dass die Teilprobleme vor der Problemlösung gelöst werden. +Dies wird als Dynamische Programmierung bezeichnet. + +## Ein Beispiel für Dynamische Programmierung + +Das Problem mit der längsten ansteigenden Subsequenz besteht darin, +die längste ansteigende Subsequenz einer gegebenen Sequenz zu finden. +Gegeben die Sequenz `S= {a1, a2, a3, a3, a4,..............., an-1, an }`, +müssen wir die größte Teilmenge finden, so daß für alle `j` und `i`, `j<i` +in der Teilmenge `aj<ai` gilt. +Zuerst müssen wir bei jedem Index i den Wert der längsten Subsequenzen (LSi) +finden, wobei das letzte Element der Sequenz ai ist. Dann wäre die größte LSi +die längste Subsequenz in der gegebenen Sequenz. Am Anfang wird der LSi mit +eins belegt, da ai ein Element der Sequenz (Letztes Element) ist. +Dann ist für alle `j` mit `j<i` und `aj<ai`, so dass wir den größten LSj finden +und zum LSi hinzufügen. Der Algorithmus hat eine Laufzeit von *O(n2)*. + +Pseudocode zur Bestimmung der Länge der am längsten ansteigenden Subsequenz: +Die Komplexität des Algorithmus könnte durch eine bessere Datenstruktur anstelle +von Arrays reduziert werden. Das Speichern von Vorgänger-Array's und Variablen +wie `largest_sequences_so_far` und dessen Index würde eine Menge Zeit sparen. + +Ein ähnliches Konzept könnte auch bei der Suche nach dem längsten Weg +in gerichteten azyklischen Graphen angewandt werden. +```python +for i=0 to n-1 + LS[i]=1 + for j=0 to i-1 + if (a[i] > a[j] and LS[i]<LS[j]) + LS[i] = LS[j]+1 +for i=0 to n-1 + if (largest < LS[i]) +``` + +### Einige bekannte DP Probleme + +- Floyd Warshall Algorithm - [Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code) +- Integer Knapsack Problem - [Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem) +- Longest Common Subsequence - [Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence) + +## Online Ressourcen + +* [codechef](https://www.codechef.com/wiki/tutorial-dynamic-programming) diff --git a/elm.html.markdown b/elm.html.markdown index 23ae9eeb..ad80adc9 100644 --- a/elm.html.markdown +++ b/elm.html.markdown @@ -72,8 +72,8 @@ List.head [] -- Nothing -- Access the elements of a pair with the first and second functions. -- (This is a shortcut; we'll come to the "real way" in a bit.) -fst ("elm", 42) -- "elm" -snd ("elm", 42) -- 42 +Tuple.first ("elm", 42) -- "elm" +Tuple.second ("elm", 42) -- 42 -- The empty tuple, or "unit", is sometimes used as a placeholder. -- It is the only value of its type, also called "Unit". diff --git a/fr-fr/crystal-fr.html.markdown b/fr-fr/crystal-fr.html.markdown index 2c4e3dad..2bb17fc5 100644 --- a/fr-fr/crystal-fr.html.markdown +++ b/fr-fr/crystal-fr.html.markdown @@ -305,7 +305,6 @@ end (1..3).each do |index| puts "Index: #{index}" end -# Index: 0 # Index: 1 # Index: 2 # Index: 3 diff --git a/fr-fr/php-fr.html.markdown b/fr-fr/php-fr.html.markdown index d001f1d4..45a02d75 100644 --- a/fr-fr/php-fr.html.markdown +++ b/fr-fr/php-fr.html.markdown @@ -10,8 +10,6 @@ translators: lang: fr-fr --- -This document describes PHP 5+. - Ce document décrit PHP 5+. ```php diff --git a/go.html.markdown b/go.html.markdown index e5263cf6..47d9c234 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -180,7 +180,7 @@ func learnFlowControl() { if true { fmt.Println("told ya") } - // Formatting is standardized by the command line command "go fmt." + // Formatting is standardized by the command line command "go fmt". if false { // Pout. } else { diff --git a/hu-hu/python-hu.html.markdown b/hu-hu/python-hu.html.markdown new file mode 100644 index 00000000..9b55f8e2 --- /dev/null +++ b/hu-hu/python-hu.html.markdown @@ -0,0 +1,816 @@ +--- +language: python +contributors: + - ["Louie Dinh", "http://ldinh.ca"] + - ["Amin Bandali", "https://aminb.org"] + - ["Andre Polykanine", "https://github.com/Oire"] + - ["evuez", "http://github.com/evuez"] + - ["asyne", "https://github.com/justblah"] + - ["habi", "http://github.com/habi"] +translators: + - ["Tamás Diószegi", "https://github.com/ditam"] +filename: learnpython-hu.py +lang: hu-hu +--- + +A Python nyelvet Guido Van Rossum alkotta meg a 90-es évek elején. Manapság az +egyik legnépszerűbb programozási nyelv. Én a tiszta szintaxisa miatt szerettem +bele. Tulajdonképpen futtatható pszeudokód. + +Szívesen fogadok visszajelzéseket! Elérsz itt: [@louiedinh](http://twitter.com/louiedinh) +vagy pedig a louiedinh [kukac] [google email szolgáltatása] címen. + +Figyelem: ez a leírás a Python 2.7 verziójára vonatkozok, illetve +általánosságban a 2.x verziókra. A Python 2.7 azonban már csak 2020-ig lesz +támogatva, ezért kezdőknek ajánlott, hogy a Python 3-mal kezdjék az +ismerkedést. A Python 3.x verzióihoz a [Python 3 bemutató](http://learnxinyminutes.com/docs/python3/) +ajánlott. + +Lehetséges olyan Python kódot írni, ami egyszerre kompatibilis a 2.7 és a 3.x +verziókkal is, a Python [`__future__` imports](https://docs.python.org/2/library/__future__.html) használatával. +A `__future__` import használata esetén Python 3-ban írhatod a kódot, ami +Python 2 alatt is futni fog, így ismét a fenti Python 3 bemutató ajánlott. + +```python + +# Az egysoros kommentek kettőskereszttel kezdődnek + +""" Többsoros stringeket három darab " közé + fogva lehet írni, ezeket gyakran használják + több soros kommentként. +""" + +#################################################### +# 1. Egyszerű adattípusok és operátorok +#################################################### + +# Használhatsz számokat +3 # => 3 + +# Az alapműveletek meglepetésektől mentesek +1 + 1 # => 2 +8 - 1 # => 7 +10 * 2 # => 20 +35 / 5 # => 7 + +# Az osztás kicsit trükkös. Egész osztást végez, és a hányados alsó egész része +# lesz az eredmény +5 / 2 # => 2 + +# Az osztás kijavításához a (lebegőpontos) float típust kell használnunk +2.0 # Ez egy float +11.0 / 4.0 # => 2.75 áh... máris jobb + +# Az egész osztás a negatív számok esetén is az alsó egész részt eredményezi +5 // 3 # => 1 +5.0 // 3.0 # => 1.0 # floatok esetén is +-5 // 3 # => -2 +-5.0 // 3.0 # => -2.0 + +# Ha importáljuk a division modult (ld. 6. Modulok rész), +# akkor a '/' jellel pontos osztást tudunk végezni. +from __future__ import division + +11 / 4 # => 2.75 ...sima osztás +11 // 4 # => 2 ...egész osztás + +# Modulo művelet +7 % 3 # => 1 + +# Hatványozás (x az y. hatványra) +2 ** 4 # => 16 + +# A precedencia zárójelekkel befolyásolható +(1 + 3) * 2 # => 8 + +# Logikai operátorok +# Megjegyzés: az "and" és "or" csak kisbetűkkel helyes +True and False # => False +False or True # => True + +# A logikai operátorok egészeken is használhatóak +0 and 2 # => 0 +-5 or 0 # => -5 +0 == False # => True +2 == True # => False +1 == True # => True + +# Negálni a not kulcsszóval lehet +not True # => False +not False # => True + +# Egyenlőségvizsgálat == +1 == 1 # => True +2 == 1 # => False + +# Egyenlőtlenség != +1 != 1 # => False +2 != 1 # => True + +# További összehasonlítások +1 < 10 # => True +1 > 10 # => False +2 <= 2 # => True +2 >= 2 # => True + +# Az összehasonlítások láncolhatóak! +1 < 2 < 3 # => True +2 < 3 < 2 # => False + +# Stringeket " vagy ' jelek közt lehet megadni +"Ez egy string." +'Ez egy másik string.' + +# A stringek összeadhatóak! +"Hello " + "world!" # => "Hello world!" +# '+' jel nélkül is összeadhatóak +"Hello " "world!" # => "Hello world!" + +# ... illetve szorozhatóak +"Hello" * 3 # => "HelloHelloHello" + +# Kezelhető karakterek indexelhető listájaként +"This is a string"[0] # => 'T' + +# A string hosszát a len függvény adja meg +len("This is a string") # => 16 + +# String formázáshoz a % jel használható +# A Python 3.1-gyel a % már deprecated jelölésű, és később eltávolításra fog +# kerülni, de azért jó tudni, hogyan működik. +x = 'alma' +y = 'citrom' +z = "A kosárban levő elemek: %s és %s" % (x, y) + +# A string formázás újabb módja a format metódus használatával történik. +# Jelenleg ez a javasolt megoldás. +"{} egy {} szöveg".format("Ez", "helytartó") +"A {0} pedig {1}".format("string", "formázható") +# Ha nem akarsz számolgatni, nevesíthetőek a pozíciók. +"{name} kedvence a {food}".format(name="Bob", food="lasagna") + +# None egy objektum +None # => None + +# A None-nal való összehasonlításhoz ne használd a "==" jelet, +# használd az "is" kulcsszót helyette +"etc" is None # => False +None is None # => True + +# Az 'is' operátor objektum egyezést vizsgál. +# Primitív típusok esetén ez nem túl hasznos, +# objektumok esetén azonban annál inkább. + +# Bármilyen objektum használható logikai kontextusban. +# A következő értékek hamis-ra értékelődnek ki (ún. "falsey" értékek): +# - None +# - bármelyik szám típus 0 értéke (pl. 0, 0L, 0.0, 0j) +# - üres sorozatok (pl. '', (), []) +# - üres konténerek (pl., {}, set()) +# - egyes felhasználó által definiált osztályok példányai bizonyos szabályok szerint, +# ld: https://docs.python.org/2/reference/datamodel.html#object.__nonzero__ +# +# Minden egyéb érték "truthy" (a bool() függvénynek átadva igazra értékelődnek ki) +bool(0) # => False +bool("") # => False + + +#################################################### +# 2. Változók és kollekciók +#################################################### + +# Létezik egy print utasítás +print "I'm Python. Nice to meet you!" # => I'm Python. Nice to meet you! + +# Így lehet egyszerűen bemenetet kérni a konzolról: +input_string_var = raw_input( + "Enter some data: ") # Visszatér a megadott stringgel +input_var = input("Enter some data: ") # Kiértékeli a bemenetet python kódként +# Vigyázat: a fentiek miatt az input() metódust körültekintően kell használni +# Megjegyzés: Python 3-ban az input() már deprecated, és a raw_input() lett input()-ra átnevezve + +# A változókat nem szükséges a használat előtt deklarálni +some_var = 5 # Konvenció szerint a névben kisbetu_es_alulvonas +some_var # => 5 + +# Érték nélküli változóra hivatkozás hibát dob. +# Lásd a Control Flow szekciót a kivételkezelésről. +some_other_var # name error hibát dob + +# az if használható kifejezésként +# a C nyelv '?:' ternáris operátorával egyenértékűen +"yahoo!" if 3 > 2 else 2 # => "yahoo!" + +# A listákban sorozatok tárolhatóak +li = [] +# Már inicializáláskor megadhatóak elemek +other_li = [4, 5, 6] + +# A lista végére az append metódus rak új elemet +li.append(1) # li jelenleg [1] +li.append(2) # li jelenleg [1, 2] +li.append(4) # li jelenleg [1, 2, 4] +li.append(3) # li jelenleg [1, 2, 4, 3] +# A végéről a pop metódus távolít el elemet +li.pop() # => 3 és li jelenleg [1, 2, 4] +# Rakjuk vissza +li.append(3) # li jelenleg [1, 2, 4, 3], újra. + +# A lista elemeket tömb indexeléssel lehet hivatkozni +li[0] # => 1 +# A már inicializált értékekhez a = jellel lehet új értéket rendelni +li[0] = 42 +li[0] # => 42 +li[0] = 1 # csak visszaállítjuk az eredeti értékére +# Így is lehet az utolsó elemre hivatkozni +li[-1] # => 3 + +# A túlindexelés eredménye IndexError +li[4] # IndexError hibát dob + +# A lista részeit a slice szintaxissal lehet kimetszeni +# (Matekosoknak ez egy zárt/nyitott intervallum.) +li[1:3] # => [2, 4] +# A lista eleje kihagyható így +li[2:] # => [4, 3] +# Kihagyható a vége +li[:3] # => [1, 2, 4] +# Minden második elem kiválasztása +li[::2] # =>[1, 4] +# A lista egy másolata, fordított sorrendben +li[::-1] # => [3, 4, 2, 1] +# A fentiek kombinációival bonyolultabb slice parancsok is képezhetőek +# li[start:end:step] + +# Listaelemek a "del" paranccsal törölhetőek +del li[2] # li jelenleg [1, 2, 3] + +# A listák összeadhatóak +li + other_li # => [1, 2, 3, 4, 5, 6] +# Megjegyzés: az eredeti li és other_li értékei változatlanok + +# Összefőzhetőek (konkatenálhatóak) az "extend()" paranccsal +li.extend(other_li) # li jelenleg [1, 2, 3, 4, 5, 6] + +# Egy elem első előfordulásának eltávolítása +li.remove(2) # li jelenleg [1, 3, 4, 5, 6] +li.remove(2) # ValueError hibát dob, mivel a 2 nem szerepel már a listában + +# Elemek beszúrhatóak tetszőleges helyre +li.insert(1, 2) # li jelenleg [1, 2, 3, 4, 5, 6], ismét + +# Egy elem első előfordulási helye +li.index(2) # => 1 +li.index(7) # ValueError hibát dob, mivel a 7 nem szerepel a listában + +# Egy listában egy elem előfordulása az "in" szóval ellenőrizhető +1 in li # => True + +# A lista hossza a "len()" függvénnyel +len(li) # => 6 + +# Az N-esek ("tuple") hasonlítanak a listákhoz, de nem módosíthatóak +tup = (1, 2, 3) +tup[0] # => 1 +tup[0] = 3 # TypeError hibát dob + +# Az összes lista-műveletet ezeken is használható +len(tup) # => 3 +tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6) +tup[:2] # => (1, 2) +2 in tup # => True + +# Az N-esek (és listák) kicsomagolhatóak külön változókba +a, b, c = (1, 2, 3) # az a így 1, a b 2 és a c pedig 3 +d, e, f = 4, 5, 6 # a zárójel elhagyható +# Ha elhagyod a zárójeleket, alapértelmezés szerint tuple képződik +g = 4, 5, 6 # => (4, 5, 6) +# Nézd, milyen egyszerű két értéket megcserélni +e, d = d, e # d most már 5 és az e 4 + +# A Dictionary típusokban hozzárendelések (kulcs-érték párok) tárolhatók +empty_dict = {} +# Ez pedig rögtön értékekkel van inicializálva +filled_dict = {"one": 1, "two": 2, "three": 3} + +# Egy dictionary értékei [] jelek közt indexelhetőek +filled_dict["one"] # => 1 + +# A "keys()" metódus visszatér a kulcsok listájával +filled_dict.keys() # => ["three", "two", "one"] +# Megjegyzés: egy dictionary párjainak sorrendje nem garantált +# Lehet, hogy már a fenti példán is más sorrendben kaptad meg az elemeket. + +# Az értékek listája a "values()" metódussal kérhető le +filled_dict.values() # => [3, 2, 1] +# ld. a fenti megjegyzést az elemek sorrendjéről. + +# Az összes kulcs-érték pár megkapható N-esek listájaként az "items()" metódussal +filled_dict.items() # => [("one", 1), ("two", 2), ("three", 3)] + +# Az "in" kulcssszóval ellenőrizhető, hogy egy kulcs szerepel-e a dictionary-ben +"one" in filled_dict # => True +1 in filled_dict # => False + +# Nem létező kulcs hivatkozása KeyError hibát dob +filled_dict["four"] # KeyError + +# A "get()" metódus használatával elkerülhető a KeyError +filled_dict.get("one") # => 1 +filled_dict.get("four") # => None +# A metódusnak megadható egy alapértelmezett visszatérési érték is, hiányzó értékek esetén +filled_dict.get("one", 4) # => 1 +filled_dict.get("four", 4) # => 4 +# Megjegyzés: ettől még filled_dict.get("four") => None +# (vagyis a get nem állítja be az alapértelmezett értéket a dictionary-ben) + +# A kulcsokhoz értékek a listákhoz hasonló szintaxissal rendelhetőek: +filled_dict["four"] = 4 # ez után filled_dict["four"] => 4 + +# A "setdefault()" metódus csak akkor állít be egy értéket, ha az adott kulcshoz még nem volt más megadva +filled_dict.setdefault("five", 5) # filled_dict["five"] beállítva 5-re +filled_dict.setdefault("five", 6) # filled_dict["five"] még mindig 5 + +# Egy halmaz ("set") olyan, mint egy lista, de egy elemet csak egyszer tárolhat +empty_set = set() +# Inicializáljuk ezt a halmazt néhány elemmel +some_set = set([1, 2, 2, 3, 4]) # some_set jelenleg set([1, 2, 3, 4]) + +# A sorrend itt sem garantált, még ha néha rendezettnek is tűnhet +another_set = set([4, 3, 2, 2, 1]) # another_set jelenleg set([1, 2, 3, 4]) + +# Python 2.7 óta már {} jelek közt is lehet halmazt definiálni +filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4} + +# Új halmaz-elemek hozzáadása +filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5} + +# Halmaz metszés a & operátorral +other_set = {3, 4, 5, 6} +filled_set & other_set # => {3, 4, 5} + +# Halmaz unió | operátorral +filled_set | other_set # => {1, 2, 3, 4, 5, 6} + +# Halmaz különbség - +{1, 2, 3, 4} - {2, 3, 5} # => {1, 4} + +# Szimmetrikus differencia ^ +{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5} + +# Vizsgáljuk, hogy a bal oldali halmaz magában foglalja-e a jobb oldalit +{1, 2} >= {1, 2, 3} # => False + +# Vizsgáljuk, hogy a bal oldali halmaz részhalmaza-e a jobb oldalinak +{1, 2} <= {1, 2, 3} # => True + +# Halmazbeli elemek jelenléte az in kulcssszóval vizsgálható +2 in filled_set # => True +10 in filled_set # => False + + +#################################################### +# 3. Control Flow +#################################################### + +# Legyen egy változónk +some_var = 5 + +# Ez egy if elágazás. A behúzás mértéke (az indentáció) jelentéssel bír a nyelvben! +# Ez a kód ezt fogja kiírni: "some_var kisebb 10-nél" +if some_var > 10: + print "some_var nagyobb, mint 10." +elif some_var < 10: # Az elif kifejezés nem kötelező az if szerkezetben. + print "some_var kisebb 10-nél" +else: # Ez sem kötelező. + print "some_var kereken 10." + +""" +For ciklusokkal végigiterálhatunk listákon +a kimenet: + A(z) kutya emlős + A(z) macska emlős + A(z) egér emlős +""" +for animal in ["kutya", "macska", "egér"]: + # A {0} kifejezéssel formázzuk a stringet, ld. korábban. + print "A(z) {0} emlős".format(animal) + +""" +"range(number)" visszatér számok listájával 0-től number-ig +a kimenet: + 0 + 1 + 2 + 3 +""" +for i in range(4): + print i + +""" +"range(lower, upper)" visszatér a lower és upper közti számok listájával +a kimenet: + 4 + 5 + 6 + 7 +""" +for i in range(4, 8): + print i + +""" +A while ciklus a feltétel hamissá válásáig fut. +a kimenet: + 0 + 1 + 2 + 3 +""" +x = 0 +while x < 4: + print x + x += 1 # Rövidítés az x = x + 1 kifejezésre + +# A kivételek try/except blokkokkal kezelhetőek + +# Python 2.6-tól felfele: +try: + # A "raise" szóval lehet hibát dobni + raise IndexError("Ez egy index error") +except IndexError as e: + pass # A pass egy üres helytartó művelet. Itt hívnánk a hibakezelő kódunkat. +except (TypeError, NameError): + pass # Ha szükséges, egyszerre több hiba típus is kezelhető +else: # Az except blokk után opcionálisan megadható + print "Minden rendben!" # Csak akkor fut le, ha fentebb nem voltak hibák +finally: # Mindenképpen lefut + print "Itt felszabadíthatjuk az erőforrásokat például" + +# Az erőforrások felszabadításához try/finally helyett a with használható +with open("myfile.txt") as f: + for line in f: + print line + + +#################################################### +# 4. Függvények +#################################################### + +# A "def" szóval hozhatunk létre új függvényt +def add(x, y): + print "x is {0} and y is {1}".format(x, y) + return x + y # A return szóval tudunk értékeket visszaadni + + +# Így hívunk függvényt paraméterekkel +add(5, 6) # => a konzol kimenet "x is 5 and y is 6", a visszatérési érték 11 + +# Nevesített paraméterekkel (ún. "keyword arguments") is hívhatunk egy függvényt +add(y=6, x=5) # Ez esetben a sorrendjük nem számít + + +# Változó számú paramétert fogadó függvény így definiálható. +# A * használatával a paramétereket egy N-esként kapjuk meg. +def varargs(*args): + return args + + +varargs(1, 2, 3) # => (1, 2, 3) + + +# Változó számú nevesített paramétert fogadó függvény is megadható, +# a ** használatával a paramétereket egy dictionary-ként kapjuk meg +def keyword_args(**kwargs): + return kwargs + + +# Nézzük meg, mi történik +keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"} + + +# A két módszer egyszerre is használható +def all_the_args(*args, **kwargs): + print args + print kwargs + + +""" +all_the_args(1, 2, a=3, b=4) kimenete: + (1, 2) + {"a": 3, "b": 4} +""" + +# Függvények hívásakor a fenti args és kwargs módszerek inverze használható +# A * karakter kifejt egy listát külön paraméterekbe, a ** egy dictionary-t nevesített paraméterekbe. +args = (1, 2, 3, 4) +kwargs = {"a": 3, "b": 4} +all_the_args(*args) # egyenértékű: foo(1, 2, 3, 4) +all_the_args(**kwargs) # egyenértékű: foo(a=3, b=4) +all_the_args(*args, **kwargs) # egyenértékű: foo(1, 2, 3, 4, a=3, b=4) + + +# A fenti arg és kwarg paraméterek továbbadhatóak egyéb függvényeknek, +# a * illetve ** operátorokkal kifejtve +def pass_all_the_args(*args, **kwargs): + all_the_args(*args, **kwargs) + print varargs(*args) + print keyword_args(**kwargs) + + +# Függvény scope +x = 5 + + +def set_x(num): + # A lokális x változó nem ugyanaz, mint a globális x + x = num # => 43 + print x # => 43 + + +def set_global_x(num): + global x + print x # => 5 + x = num # a globális x-et 6-ra állítjuk + print x # => 6 + + +set_x(43) +set_global_x(6) + + +# A pythonban a függvény elsőrendű (ún. "first class") típus +def create_adder(x): + def adder(y): + return x + y + + return adder + + +add_10 = create_adder(10) +add_10(3) # => 13 + +# Névtelen függvények is definiálhatóak +(lambda x: x > 2)(3) # => True +(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5 + +# Léteznek beépített magasabb rendű függvények +map(add_10, [1, 2, 3]) # => [11, 12, 13] +map(max, [1, 2, 3], [4, 2, 1]) # => [4, 2, 3] + +filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7] + +# A listaképző kifejezések ("list comprehensions") jól használhatóak a map és filter függvényekkel +[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] +[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7] + +# halmaz és dictionary képzők is léteznek +{x for x in 'abcddeef' if x in 'abc'} # => {'a', 'b', 'c'} +{x: x ** 2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} + + +#################################################### +# 5. Osztályok +#################################################### + +# Az object osztály egy alosztályát képezzük +class Human(object): + # Osztály szintű mező: az osztály összes példányában azonos + species = "H. sapiens" + + # Ez a függvény meghívódik az osztály példányosításakor. + # Megjegyzés: a dupla aláhúzás a név előtt és után egy konvenció a python + # előre definiált, a nyelv által belsőleg használt, de a felhasználó által + # is látható objektumok és mezők neveire. + # Ne vezessünk be új, ilyen elnevezési sémát használó neveket! + def __init__(self, name): + # A paramétert értékül adjuk a példány name attribútumának + self.name = name + + # Inicializálunk egy mezőt + self.age = 0 + + # Példány metódus. Minden metódus első paramétere a "self", a példány maga + def say(self, msg): + return "{0}: {1}".format(self.name, msg) + + # Egy osztálymetódus az osztály összes példány közt meg van osztva. + # Hívásukkor az első paraméter mindig a hívó osztály. + @classmethod + def get_species(cls): + return cls.species + + # Egy statikus metódus osztály és példányreferencia nélkül hívódik + @staticmethod + def grunt(): + return "*grunt*" + + # Egy property jelölésű függvény olyan, mint egy getter. + # Használatával az age mező egy csak-olvasható attribútummá válik. + @property + def age(self): + return self._age + + # Így lehet settert megadni egy mezőhöz + @age.setter + def age(self, age): + self._age = age + + # Így lehet egy mező törlését engedélyezni + @age.deleter + def age(self): + del self._age + + +# Példányosítsuk az osztályt +i = Human(name="Ian") +print i.say("hi") # kimenet: "Ian: hi" + +j = Human("Joel") +print j.say("hello") # kimenet: "Joel: hello" + +# Hívjuk az osztály metódusunkat +i.get_species() # => "H. sapiens" + +# Változtassuk meg az osztály szintű attribútumot +Human.species = "H. neanderthalensis" +i.get_species() # => "H. neanderthalensis" +j.get_species() # => "H. neanderthalensis" + +# Hívjuk meg a statikus metódust +Human.grunt() # => "*grunt*" + +# Adjunk új értéket a mezőnek +i.age = 42 + +# Kérjük le a mező értékét +i.age # => 42 + +# Töröljük a mezőt +del i.age +i.age # => AttributeError hibát dob + +#################################################### +# 6. Modulok +#################################################### + +# Modulokat így lehet importálni +import math + +print math.sqrt(16) # => 4 + +# Lehetséges csak bizonyos függvényeket importálni egy modulból +from math import ceil, floor + +print ceil(3.7) # => 4.0 +print floor(3.7) # => 3.0 + +# Egy modul összes függvénye is importálható +# Vigyázat: ez nem ajánlott. +from math import * + +# A modulok nevei lerövidíthetőek +import math as m + +math.sqrt(16) == m.sqrt(16) # => True +# Meggyőződhetünk róla, hogy a függvények valóban azonosak +from math import sqrt + +math.sqrt == m.sqrt == sqrt # => True + +# A Python modulok egyszerű fájlok. +# Írhatsz sajátot és importálhatod is. +# A modul neve azonos a tartalmazó fájl nevével. + +# Így lehet megtekinteni, milyen mezőket és függvényeket definiál egy modul. +import math + +dir(math) + + +# Ha van egy math.py nevű Python scripted a jelenleg futó scripttel azonos +# mappában, a math.py fájl lesz betöltve a beépített Python modul helyett. +# A lokális mappa prioritást élvez a beépített könyvtárak felett. + + +#################################################### +# 7. Haladóknak +#################################################### + +# Generátorok +# Egy generátor értékeket "generál" amikor kérik, a helyett, hogy előre eltárolná őket. + +# A következő metódus (ez még NEM egy generátor) megduplázza a kapott iterable elemeit, +# és eltárolja őket. Nagy méretű iterable esetén ez nagyon sok helyet foglalhat! +def double_numbers(iterable): + double_arr = [] + for i in iterable: + double_arr.append(i + i) + return double_arr + + +# A következő kód futtatásakor az összes szám kétszeresét kiszámítanánk, és visszaadnánk +# ezt a nagy listát a ciklus vezérléséhez. +for value in double_numbers(range(1000000)): # `test_non_generator` + print value + if value > 5: + break + + +# Használjunk inkább egy generátort, ami "legenerálja" a soron következő elemet, +# amikor azt kérik tőle +def double_numbers_generator(iterable): + for i in iterable: + yield i + i + + +# A lenti kód mindig csak a soron következő számot generálja a logikai vizsgálat előtt. +# Így amikor az érték eléri a > 5 határt, megszakítjuk a ciklust, és a lista számainak +# nagy részénél megspóroltuk a duplázás műveletet (ez sokkal gyorsabb így!). +for value in double_numbers_generator(xrange(1000000)): # `test_generator` + print value + if value > 5: + break + +# Feltűnt, hogy a `test_non_generator` esetén `range`, a `test_generator` esetén +# pedig `xrange` volt a segédfüggvény neve? Ahogy `double_numbers_generator` a +# generátor változata a `double_numbers` függvénynek, úgy az `xrange` a `range` +# generátor megfelelője, csak akkor generálja le a következő számot, amikor kérjük +# - esetünkben a ciklus következő iterációjakor + +# A lista képzéshez hasonlóan generátor képzőket is használhatunk +# ("generator comprehensions"). +values = (-x for x in [1, 2, 3, 4, 5]) +for x in values: + print(x) # kimenet: -1 -2 -3 -4 -5 + +# Egy generátor összes generált elemét listaként is elkérhetjük: +values = (-x for x in [1, 2, 3, 4, 5]) +gen_to_list = list(values) +print(gen_to_list) # => [-1, -2, -3, -4, -5] + +# Dekorátorok +# A dekorátor egy magasabb rendű függvény, aminek bemenete és kimenete is egy függvény. +# A lenti egyszerű példában az add_apples dekorátor a dekorált get_fruits függvény +# kimenetébe beszúrja az 'Apple' elemet. +def add_apples(func): + def get_fruits(): + fruits = func() + fruits.append('Apple') + return fruits + return get_fruits + +@add_apples +def get_fruits(): + return ['Banana', 'Mango', 'Orange'] + +# A kimenet tartalmazza az 'Apple' elemet: +# Banana, Mango, Orange, Apple +print ', '.join(get_fruits()) + +# Ebben a példában a beg dekorátorral látjuk el a say függvényt. +# Beg meghívja say-t. Ha a say_please paraméter igaz, akkor +# megváltoztatja az eredmény mondatot. +from functools import wraps + + +def beg(target_function): + @wraps(target_function) + def wrapper(*args, **kwargs): + msg, say_please = target_function(*args, **kwargs) + if say_please: + return "{} {}".format(msg, "Please! I am poor :(") + return msg + + return wrapper + + +@beg +def say(say_please=False): + msg = "Can you buy me a beer?" + return msg, say_please + + +print say() # Can you buy me a beer? +print say(say_please=True) # Can you buy me a beer? Please! I am poor :( +``` + +## Még több érdekel? + +### Ingyenes online tartalmak + +* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com) +* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/) +* [Dive Into Python](http://www.diveintopython.net/) +* [The Official Docs](http://docs.python.org/2/) +* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/) +* [Python Module of the Week](http://pymotw.com/2/) +* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182) +* [First Steps With Python](https://realpython.com/learn/python-first-steps/) +* [LearnPython](http://www.learnpython.org/) +* [Fullstack Python](https://www.fullstackpython.com/) + +### Könyvek + +* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20) +* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20) +* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20) diff --git a/java.html.markdown b/java.html.markdown index dd875c16..ab2be4a2 100644 --- a/java.html.markdown +++ b/java.html.markdown @@ -44,8 +44,6 @@ import java.util.ArrayList; // Import all classes inside of java.security package import java.security.*; -// Each .java file contains one outer-level public class, with the same name -// as the file. public class LearnJava { // In order to run a java program, it must have a main method as an entry diff --git a/javascript.html.markdown b/javascript.html.markdown index 199c3c09..e7066291 100644 --- a/javascript.html.markdown +++ b/javascript.html.markdown @@ -607,6 +607,10 @@ some of the more complicated examples. [Javascript: The Right Way][10] is a guide intended to introduce new developers to JavaScript and help experienced developers learn more about its best practices. +[Javascript:Info][11] is a modern javascript tutorial covering the basics (core language and working with a browser) +as well as advanced topics with concise explanations. + + In addition to direct contributors to this article, some content is adapted from Louie Dinh's Python tutorial on this site, and the [JS Tutorial][7] on the Mozilla Developer Network. @@ -622,3 +626,4 @@ Mozilla Developer Network. [8]: http://eloquentjavascript.net/ [9]: http://watchandcode.com/courses/eloquent-javascript-the-annotated-version [10]: http://jstherightway.org/ +[11]: https://javascript.info/ diff --git a/lambda-calculus.html.markdown b/lambda-calculus.html.markdown new file mode 100644 index 00000000..6103c015 --- /dev/null +++ b/lambda-calculus.html.markdown @@ -0,0 +1,121 @@ +--- +category: Algorithms & Data Structures +name: Lambda Calculus +contributors: + - ["Max Sun", "http://github.com/maxsun"] +--- + +# Lambda Calculus + +Lambda calculus (λ-calculus), originally created by +[Alonzo Church](https://en.wikipedia.org/wiki/Alonzo_Church), +is the world's smallest programming language. +Despite not having numbers, strings, booleans, or any non-function datatype, +lambda calculus can be used to represent any Turing Machine! + +Lambda calculus is composed of 3 elements: **variables**, **functions**, and +**applications**. + + +| Name | Syntax | Example | Explanation | +|-------------|------------------------------------|-----------|-----------------------------------------------| +| Variable | `<name>` | `x` | a variable named "x" | +| Function | `λ<parameters>.<body>` | `λx.x` | a function with parameter "x" and body "x" | +| Application | `<function><variable or function>` | `(λx.x)a` | calling the function "λx.x" with argument "a" | + +The most basic function is the identity function: `λx.x` which is equivalent to +`f(x) = x`. The first "x" is the function's argument, and the second is the +body of the function. + +## Free vs. Bound Variables: + +- In the function `λx.x`, "x" is called a bound variable because it is both in +the body of the function and a parameter. +- In `λx.y`, "y" is called a free variable because it is never declared before hand. + +## Evaluation: + +Evaluation is done via +[β-Reduction](https://en.wikipedia.org/wiki/Lambda_calculus#Beta_reduction), +which is essentially lexically-scoped substitution. + +When evaluating the +expression `(λx.x)a`, we replace all occurences of "x" in the function's body +with "a". + +- `(λx.x)a` evaluates to: `a` +- `(λx.y)a` evaluates to: `y` + +You can even create higher-order functions: + +- `(λx.(λy.x))a` evaluates to: `λy.a` + +Although lambda calculus traditionally supports only single parameter +functions, we can create multi-parameter functions using a technique called +[currying](https://en.wikipedia.org/wiki/Currying). + +- `(λx.λy.λz.xyz)` is equivalent to `f(x, y, z) = x(y(z))` + +Sometimes `λxy.<body>` is used interchangeably with: `λx.λy.<body>` + +---- + +It's important to recognize that traditional **lambda calculus doesn't have +numbers, characters, or any non-function datatype!** + +## Boolean Logic: + +There is no "True" or "False" in lambda calculus. There isn't even a 1 or 0. + +Instead: + +`T` is represented by: `λx.λy.x` + +`F` is represented by: `λx.λy.y` + +First, we can define an "if" function `λbtf` that +returns `t` if `b` is True and `f` if `b` is False + +`IF` is equivalent to: `λb.λt.λf.b t f` + +Using `IF`, we can define the basic boolean logic operators: + +`a AND b` is equivalent to: `λab.IF a b F` + +`a OR b` is equivalent to: `λab.IF a T b` + +`a NOT b` is equivalent to: `λa.IF a F T` + +*Note: `IF a b c` is essentially saying: `IF(a(b(c)))`* + +## Numbers: + +Although there are no numbers in lambda calculus, we can encode numbers using +[Church numerals](https://en.wikipedia.org/wiki/Church_encoding). + +For any number n: <code>n = λf.f<sup>n</sup></code> so: + +`0 = λf.λx.x` + +`1 = λf.λx.f x` + +`2 = λf.λx.f(f x)` + +`3 = λf.λx.f(f(f x))` + +To increment a Church numeral, +we use the successor function `S(n) = n + 1` which is: + +`S = λn.λf.λx.f((n f) x)` + +Using successor, we can define add: + +`ADD = λab.(a S)n` + +**Challenge:** try defining your own multiplication function! + +## For more advanced reading: + +1. [A Tutorial Introduction to the Lambda Calculus](http://www.inf.fu-berlin.de/lehre/WS03/alpi/lambda.pdf) +2. [Cornell CS 312 Recitation 26: The Lambda Calculus](http://www.cs.cornell.edu/courses/cs3110/2008fa/recitations/rec26.html) +3. [Wikipedia - Lambda Calculus](https://en.wikipedia.org/wiki/Lambda_calculus)
\ No newline at end of file diff --git a/latex.html.markdown b/latex.html.markdown index a3866892..c9b1d8fb 100644 --- a/latex.html.markdown +++ b/latex.html.markdown @@ -255,7 +255,7 @@ There exists two main types of links: visible URL \\ % You can not add extra-spaces or special symbols into shadowing text since it % will cause mistakes during the compilation -This package also produces list of tumbnails in the output pdf document and +This package also produces list of thumbnails in the output pdf document and active links in the table of contents. \section{End} diff --git a/nl-nl/html-nl.html.markdown b/nl-nl/html-nl.html.markdown new file mode 100644 index 00000000..54c81ed6 --- /dev/null +++ b/nl-nl/html-nl.html.markdown @@ -0,0 +1,98 @@ +--- +language: html +filename: learnhtml-nl.html +contributors: + - ["Christophe THOMAS", "https://github.com/WinChris"] +translators: + - ["Robert Steed", "https://github.com/robochat"] + - ["Jeroen Deviaene", "https://github.com/jerodev"] +lang: nl-nl +--- + +HTML staat voor HyperText Markup Language. +Het is een taal die je toe staat pagina's te maken op het World Wide Web. +Het is een opmaak taal, dit staat de gebruiker toe om webpagina's te maken in code en zo aan te duiden hoe de pagina moet weergegeven worden. +Eigenlijk zijn html files zelfs simpele tekst bestanden. +Wat is deze opmaak? Het is een manier om de structuur en data op de pagina weer te geven met speciale html tags. +Deze tags dienen om de betekenis te geven aan de tekst die het bevat. +Zoals vele computer talen heeft html vele verschillende versies. Hier zullen we HTML5 bespreken. + +**Merk op:** Je kan de verschillende tags en elementen testen terwijl je door de tutorial gaat met een website zoals [codepen](http://codepen.io/pen/), zo kan je de effecten hier van live zien. +Dit artikel gaat vooral over de HTML syntax en enkele handige tips + + +```html +<!-- Commentaren worden toegevoegd zoals deze lijn --> + +<!-- #################### De Tags #################### --> + +<!-- Hier is een voorbeeld HTML bestand dat we zullen analyseren. --> + +<!doctype html> + <html> + <head> + <title>Mijn Website</title> + </head> + <body> + <h1>Hello, world!</h1> + <a href="http://codepen.io/anon/pen/xwjLbZ">Neem een kijkje op deze link</a> + <p>Dit is een paragraaf.</p> + <p>Dit is nog een paragraaf.</p> + <ul> + <li>Dit is een item in een niet genummerde lijst</li> + <li>Dit is nog zo een item</li> + <li>En dit is het laatste item van de lijst</li> + </ul> + </body> + </html> + +<!-- Een HTML bestand start altijd met een tag die aan de browser laat weten dat we HTML gebruiken --> +<!doctype html> + +<!-- Daarna openen we de root van het bestand met de <html> tag --> +<html> + +<!-- Deze tag moet ook gesloten worden op het einde van het bestand --> +</html> + +<!-- Niets mag nog na deze tag komen! --> + +<!-- Binnenin (tussen de html tags <html></html>) vinden we: --> + +<!-- Een header, gedefigneerd door <head> (Deze moet gesloten worden met </head>) --> +<!-- De header bevat beschrijvingen en externe data die niet zichtbaar is op de website; Dit is metadata --> + +<head> + <title>Mijn Website</title><!-- De <title> tag geeft de tekst aan die in de titelbar van de browser moet weergegeven worden. --> +</head> + +<!-- Achter de <head> sectie vinden we bijna altijd <body> --> +<!-- Tot op dit punt is nog niets verschenen in het browser venster. --> +<!-- In de body plaatsen we wat zichtbaar moet zijn in de browser --> + +<body> + <h1>Hello, world!</h1> <!-- De h1 tag maakt een titel. --> + <!-- Er zijn ook sub titels voor <h1> van belangrijk <h2> tot minder belangrijk <h6>. --> + <a href="http://codepen.io/anon/pen/xwjLbZ">Neem een kijkje op deze link</a> <!-- een hyperlink naar de aangegeven link waar op geklikt kan worden in de browser --> + <p>This is a paragraph.</p> <!-- De tag <p> laat ons tekst toevoegen. --> + <p>This is another paragraph.</p> + <ul> <!-- De tag <ul> maakt een lijst met puntjes. --> + <!-- Om een genummerde lijst te hebben gebruik je <ol>, hiermee worden de elementen <li> automatisch genummerd --> + <li>This is an item in a non-enumerated list (bullet list)</li> + <li>This is another item</li> + <li>And this is the last item on the list</li> + </ul> +</body> + +<!-- En dat is het! Zo gemakkelijk is het om een html bestand te maken. --> +``` + +## Gebruik + +HTML wordt altijd opgeslagen in bestanden die eindigen in `.html`. + +## Meer weten + +* [wikipedia](https://nl.wikipedia.org/wiki/HTML) +* [HTML tutorial](https://developer.mozilla.org/en-US/docs/Web/HTML) +* [W3School](http://www.w3schools.com/html/html_intro.asp) diff --git a/perl6.html.markdown b/perl6.html.markdown index 2821f0d4..04f9c6e3 100644 --- a/perl6.html.markdown +++ b/perl6.html.markdown @@ -1366,7 +1366,7 @@ sub add($a, $b) { $a + $b } say [[&add]] 1, 2, 3; #=> 6 ## * Zip meta-operator -## This one is an infix meta-operator than also can be used as a "normal" +## This one is an infix meta-operator that also can be used as a "normal" ## operator. It takes an optional binary function (by default, it just creates ## a pair), and will pop one value off of each array and call its binary ## function on these until it runs out of elements. It returns an array with @@ -1659,7 +1659,7 @@ sub MAIN($name) { say "Hello, $name !" } ## Usage: ## t.pl <name> -## And since it's a regular Perl 6 sub, you can haz multi-dispatch: +## And since it's a regular Perl 6 sub, you can have multi-dispatch: ## (using a "Bool" for the named argument so that we can do `--replace` ## instead of `--replace=1`) subset File of Str where *.IO.d; # convert to IO object to check the file exists diff --git a/prolog.html.markdown b/prolog.html.markdown index 7a18a144..4f3984c7 100644 --- a/prolog.html.markdown +++ b/prolog.html.markdown @@ -104,7 +104,7 @@ magicNumber(42). ?- plus(1, 2, 3). % True ?- plus(1, 2, X). % X = 3 because 1+2 = X. ?- plus(1, X, 3). % X = 2 because 1+X = 3. -?- plus(X, 2, 3). % X = 1 because X+1 = 3. +?- plus(X, 2, 3). % X = 1 because X+2 = 3. ?- plus(X, 5, Y). % Error - although this could be solved, % the number of solutions is infinite, % which most predicates try to avoid. @@ -230,14 +230,14 @@ nearby3(X,Y) :- nearby2(X,Y). % Here is the structured comment declaration for nearby3: -%% nearby3(+X:Int, +Y:Int) is semidet. +%% nearby3(+X:Int, +Y:Int) is semideterministic. %% nearby3(+X:Int, -Y:Int) is multi. %% nearby3(-X:Int, +Y:Int) is multi. % For each variable we list a type. The + or - before the variable name % indicates if the parameter is bound (+) or free (-). The word after % "is" describes the behaviour of the predicate: -% semidet - can succeed once or fail +% semideterministic - can succeed once or fail % ( Two specific numbers are either nearby or not ) % multi - can succeed multiple times but cannot fail % ( One number surely has at least 3 nearby numbers ) @@ -267,8 +267,8 @@ character(darthVader). % Creates atom value darthVader % Note that below, writeln is used instead of print because print is % intended for debugging. -%% countTo(+X:Int) is det. -%% countUpTo(+Value:Int, +Limit:Int) is det. +%% countTo(+X:Int) is deterministic. +%% countUpTo(+Value:Int, +Limit:Int) is deterministic. countTo(X) :- countUpTo(1,X). countUpTo(Value, Limit) :- Value = Limit, writeln(Value), !. countUpTo(Value, Limit) :- Value \= Limit, writeln(Value), @@ -281,7 +281,7 @@ countUpTo(Value, Limit) :- Value \= Limit, writeln(Value), % IF test. If Value = Limit fails the second declaration is run. % There is also a more elegant syntax. -%% countUpTo2(+Value:Int, +Limit:Int) is det. +%% countUpTo2(+Value:Int, +Limit:Int) is deterministic. countUpTo2(Value, Limit) :- writeln(Value), Value = Limit -> true ; ( NextValue is Value+1, @@ -294,14 +294,14 @@ countUpTo2(Value, Limit) :- writeln(Value), % called a "failure-driven loop" to do this, but newer ones use a higher % order function. -%% countTo2(+X:Int) is det. +%% countTo2(+X:Int) is deterministic. countTo2(X) :- forall(between(1,X,Y),writeln(Y)). ?- countTo2(10). % Outputs 1 to 10 % Lists are given in square brackets. Use memberchk to check membership. % A group is safe if it doesn't include Joker or does include Batman. -%% safe(Group:list(atom)) is det. +%% safe(Group:list(atom)) is deterministic. safe(Group) :- memberchk(joker, Group) -> memberchk(batman, Group) ; true. ?- safe([robin]). % True diff --git a/pt-br/elm-pt.html.markdown b/pt-br/elm-pt.html.markdown index 78a4f1b7..d2469a93 100644 --- a/pt-br/elm-pt.html.markdown +++ b/pt-br/elm-pt.html.markdown @@ -76,8 +76,8 @@ List.head [] -- Nothing -- Acesse os elementos de um par com as funções first e second. -- (Este é um atalho; nós iremos para o "caminho real" em breve.) -fst ("elm", 42) -- "elm" -snd ("elm", 42) -- 42 +Tuple.first ("elm", 42) -- "elm" +Tuple.second ("elm", 42) -- 42 -- Uma tupla vazia ou "unidade" às vezes é utilizada como um placeholder. -- É o único valor de seu tipo, também chamado de "Unit". diff --git a/pt-br/latex-pt.html.markdown b/pt-br/latex-pt.html.markdown new file mode 100644 index 00000000..a9ed566e --- /dev/null +++ b/pt-br/latex-pt.html.markdown @@ -0,0 +1,291 @@ +--- +language: latex +contributors: + - ["Chaitanya Krishna Ande", "http://icymist.github.io"] + - ["Colton Kohnke", "http://github.com/voltnor"] + - ["Sricharan Chiruvolu", "http://sricharan.xyz"] + - ["Ramanan Balakrishnan", "https://github.com/ramananbalakrishnan"] + - ["Svetlana Golubeva", "https://attillax.github.io/"] +translators: + - ["Paulo Henrique Rodrigues Pinheiro", "https://github.com/paulohrpinheiro"] +lang: pt-br +filename: learn-latex-pt.tex +--- + +```tex +% Todas as linhas de comentários começam com % +% Não existem comentários multilinhas + +$ LaTeX não é um programa processador de textos "Visual" como +% MS Word ou OpenOffice Writer + +$ Todo comando LaTeX começa com uma barra invertida (\) + +% Documentos LaTeX começam com a definição do tipo que será % compilado +% Os tipos de documento podem ser livro, relatório, apresentação, etc. +% As opções para um documento aparecem entre [] chaves. Nesse caso +% está especificado que queremos o tamanho da fonte em 12pt. +\documentclass[12pt]{article} + +% Em seguida definimos os pacotes que o documento usa. +% Se você quiser incluir gráficos, texto colorido, ou código fonte de outra +% linguagem em outro arquivo em seu documento, você precisa ampliar as +% capacidade do LaTeX. Isso é feito adicionando-se pacotes. +% Serão incluídos os pacotes float e caption para imagens e hyperref +% para links. +\usepackage{caption} +\usepackage{float} +\usepackage{hyperref} + +% Para poder usar caracteres acentuados, use o seguinte pacote: +\usepackage[utf8]{inputenc} + +% Podemos definir algumas outras propriedades do documento também! +\author{Chaitanya Krishna Ande, Colton Kohnke, Sricharan Chiruvolu \& \\ +Svetlana Golubeva} +\date{\today} +\title{Aprenda \LaTeX \hspace{1pt} em Y Minutos!} + +% Agora estamos pronto para começar o documento +% Tudo antes dessa linha é chamado "preâmbulo". +\begin{document} +% Se informarmos os campos author (autores), date (data), "title" (título), +% LaTeX poderá cria uma página inicial para nós. +\maketitle +% Se tivermos seções, poderemos criar uma tabela de conteúdo. Para isso, +% o documento deve ser compilado duas vezes, para que tudo apareça na ordem +% correta. +% É uma voa prática separar a tabela de conteúdo do corpo do documento. Para +% isso usa-se o comando \newpage +\newpage +\tableofcontents + +\newpage + +% Muitos artigos de pesquisa possuem um resumo, e pode-se isar comandos +% predefinidos para isso. +% Isso deve aparecer em sua ordem lógica, portanto, após o topo, +% mas antes das seções principais do corpo. +% Esse comando está disponível para os documentos do tipo artigo (article) +% e relatório (report). +\begin{abstract} + Documentação do \LaTeX \hspace{1pt} escrita em \LaTeX! Nada original! +\end{abstract} + +% Comandos para seções são intuitivos. +% Todos os títulos de seção são adicionados automaticamente à tabela de conteúdo. +\section{Introdução} +Olá, meu nome é Colton e juntos estamos explorando o mundo do \LaTeX! + +\section{Outra seção} +Esse é o texto para outra seção. Penso que precisamos de uma subseção. + +\subsection{Isso é uma subseção} % Subseções também são intuitivas. +Penso que precisamos de mais uma + +\subsubsection{Pythagoras} +Muito melhor agora. +\label{subsec:pythagoras} + +% Ao usar o asterisco nós impedimos a numeração automática. +% Isso funciona para outros comandos \LaTeX também. +\section*{Essa é uma seção não numerada} +Afinal nem todas as seções precisam ser numeradas! + +\section{Algumas notas sobre texto} +%\section{Espaçamento % É necessário mais informação sobre intervalos de espaço. +\LaTeX \hspace{1pt} geralmente é muito bom sobre colocar texto onde ele deve +ser posto. Se +uma linha \\ deve \\ ser \\ quebrada \\ adicione \textbackslash\textbackslash +\hspace{1pt} ao código de seu documento. \\ + +\section{Listas} +Listas são uma das coisas mais fáceis de criar no \LaTeX! Preciso fazer compras +amanhã, então façamos uma lista de compras. +\begin{enumerate} % Isso cria o bloco "enumerate". + % \item faz com que o enumerate incremente + \item Salada. + \item 27 melancias. + \item Uma lebre. + % pode-se também sobrescrever o número do item usando [] + \item[quantas?] Pistolas de água médias. + + Não é um item da lista, mas faz parte do bloco enumerate. + + \end{enumerate} % Todos os blocos devem ter um final (end{}). + +\section{Matemática} + +Um dos usos iniciais para \LaTeX \hspace{1pt} foi a produção de artigos +acadêmicos e técnicos. Usualmente nos campos da matemática e ciência. Assim, é +necessários que consigamos incluir alguns símbolos especiais em nosso texto! \\ + +A matemática tem muitos símbolos, além dos quais se pode encontrar no teclado; +símbolos para relações e conjuntos, setas, operadores, e letras gregas, apenas +para mencionar alguns.\\ + +Conjuntos e relações são essenciais em muitos textos de pesquisa em matemática. +Aqui está como você pode indicar como todo x que pertence +a X, $\forall$ x $\in$ X. \\ +% Perceba que é necessário adicionar os sinais $ antes e depois dos símbolos. +% Isso é porque quando escrevendo, estamos em modo texto. +% Mas os símbolos de matemática só existem no modo matemática. +% Podemos entrar no modo matemática a partir do modo texto com os símbolos $. +% O oposto também pode ocorrer. Variáveis podem ser renderizadas no modo +% matemática. +% Também podemos entrar no modo matemática com \[\] + +\[a^2 + b^2 = c^2 \] + +Minha letra grega favorita é $\xi$. Eu também gosto da $\beta$, $\gamma$ e $\sigma$. +Eu ainda não encontrei uma letra grega que o \LaTeX \hspace{1pt} não tenha!\\ + +Operadores são parte essencial de um documento sobre matemática: +funções trigonométricas ($\sin$, $\cos$, $\tan$), +logaritmo e exponencial ($\log$, $\exp$), +limites ($\lim$), etc. +possuem comandos pré-definidos em LaTex. +Vamos escrever uma equação para ver como se faz: +$\cos(2\theta) = \cos^{2}(\theta) - \sin^{2}(\theta)$ \\ + +Frações (numerador/denominador) podem ser escritas dessa forma: + +% 10 / 7 +$$ ^{10}/_{7} $$ + +% Frações relativamente complexas podem ser escritas como +% \frac{numerator}{denominator} +$$ \frac{n!}{k!(n - k)!} $$ \\ + +Também podemos escrever equações em um ``bloco de equação''. + +% Apresenta matemática com o 'bloco' equação +\begin{equation} % entra no modo matemática + c^2 = a^2 + b^2. + \label{eq:pythagoras} % para referência + \end{equation} % toda declaração \begin precisa de uma declaração end + +Podemos então referenciar nossa nova equação! +A equação~\ref{eq:pythagoras} é também conhecida como Teorema de Pitágoras que é +também assunto da Seção~\ref{subsec:pythagoras}. Muitas coisas podem ser +rotuladas: figuras, equações, seções, etc. + +Somatórios e Integrais são escritas com os comandos sum e int: + +% Alguns compiladores LaTeX irão reclamar se existirem linhas em branco +% em um bloco de equação. +\begin{equation} + \sum_{i=0}^{5} f_{i} +\end{equation} +\begin{equation} + \int_{0}^{\infty} \mathrm{e}^{-x} \mathrm{d}x +\end{equation} + +\section{Figuras} + +Insiramos uma Figura. O local para colocar a figura pode ser difícil +de determinar. Eu tenho sempre que verificar as opções toda vez. + +\begin{figure}[H] % H aqui é uma opção para o local da figura. + \centering % centra a figura na página + % Inclui uma figura com escala de 0.8 do tamanho da página. + %\includegraphics[width=0.8\linewidth]{right-triangle.png} + % Comentado para propósitos de compilação. Por favor, use sua imaginação. + \caption{Triângulo retângulo com lados $a$, $b$, $c$} + \label{fig:right-triangle} +\end{figure} + +\subsection{Tabelas} +Também podemos incluir tabelas da mesma forma que figuras. + +\begin{table}[H] + \caption{Título para a Tabela.} + % os argumentos {} abaixo descrevem como cada linha da tabela é desenhada. + % Aqui também, Preciso ver isso. Toda. E. Cada. Vez. + \begin{tabular}{c|cc} + Número & Sobrenome & Primeiro Nome \\ % Colunas são separadas por & + \hline % uma linha horizontal + 1 & Biggus & Dickus \\ + 2 & Monty & Python + \end{tabular} +\end{table} + +\section{Fazendo o \LaTeX \hspace{1pt} não compilar algo (o código fonte)} +Digamos que precisamos incluir algum código dentro do nosso +documento \LaTeX \hspace{1pt}, para isso precisamos com o \LaTeX \hspace{1pt} +não tente interpretar esse texto e que apenas inclua ele no documento. Fazemos +isso com o bloco verbatim. + +% Existem outros pacotes (por exemplo, minty, lstlisting, etc.) +% mas verbatim é o básico +\begin{verbatim} + print("Hello World!") + a%b; % olha só! Podemos usar os sinais % no bloco verbatim. + random = 4; #decided by fair random dice roll +\end{verbatim} + +\section{Compilando} + +Imagino que agora você esteja pensando como compilar esse fantástico documento +e visualizar a gloriosa glória que é um pdf gerado por \LaTeX \hspace{1pt} pdf. +(sim, esse documento é compilável). \\ + +Finalizando o documento usando \LaTeX \hspace{1pt} consiste nos seguintes passos: + \begin{enumerate} + \item Escrever o documento em texto puro (o ``código fonte''). + \item Compilar o código fonte para gerar um pdf. + Os passos para compilar se parecem (em Linux) com: \\ + \begin{verbatim} + > pdflatex learn-latex.tex + \end{verbatim} + \end{enumerate} + +Existem editores de \LaTeX \hspace{1pt} que combinam os passos 1 e 2 no mesmo +sistema de software. Assim, você pode ver o passo 1, mas não o passo 2 por +completo. Passo 2 estará acontecendo escondido\footnote{Por exemplo, quando usar +referências (como Equação~\ref{eq:pythagoras}), pode ser necessário executar o +passo 2 várias vezes, para gerar arquivos *.aux intermediários.}. +% É assim que você adiciona notas de rodapé em seus documentos! + +Você escreve toda a informação de formatação em texto puro, no passo 1. O +momento da compilação no passo 2 é responsável por produzir o documento no +formato que você definiu no passo 1. + +\section{Links} +Nós podemos inserir links em nosso documento. Para isso nós necessitamos incluir +o pacote hyperref no preâmbulo com o comando: +\begin{verbatim} + \usepackage{hyperref} +\end{verbatim} + +Existem dois tipos principais de links: URL visíveis \\ +\url{https://learnxinyminutes.com/docs/latex/}, ou +\href{https://learnxinyminutes.com/docs/latex/}{um texto alternativo} +% Você não pode adicionar espaços extras ou símbolos especiais no texto +% alternativo, pois isso causará problemas na compilação. + +Esse pacote também produz uma lista de thumbnails no documento pdf gerado e +ativa os links na tabela de conteúdo. + +\section{End} + +Por enquanto é isso! + +% Frequentemente você precisa de uma seção de referências em seu documento. +% A forma mais fácil de configurá-la é usando uma seção de bibliografia +\begin{thebibliography}{1} + % como em outras listas, o comando \bibitem pode ser usado para itens da lista + % cada entrada pode ser citada diretamente no corpo do texto + \bibitem{latexwiki} The amazing \LaTeX \hspace{1pt} wikibook: {\em +https://en.wikibooks.org/wiki/LaTeX} + \bibitem{latextutorial} An actual tutorial: {\em http://www.latex-tutorial.com} +\end{thebibliography} + +% end the document +\end{document} +``` + +## Mais sobre LaTeX + +* The amazing LaTeX wikibook: [https://en.wikibooks.org/wiki/LaTeX](https://en.wikibooks.org/wiki/LaTeX) +* An actual tutorial: [http://www.latex-tutorial.com/](http://www.latex-tutorial.com/) diff --git a/pythonstatcomp.html.markdown b/pythonstatcomp.html.markdown index 79bbcd8d..6dde1cf0 100644 --- a/pythonstatcomp.html.markdown +++ b/pythonstatcomp.html.markdown @@ -13,10 +13,11 @@ This is a tutorial on how to do some typical statistical programming tasks using # 0. Getting set up ==== -""" Get set up with IPython and pip install the following: numpy, scipy, pandas, +""" To get started, pip install the following: jupyter, numpy, scipy, pandas, matplotlib, seaborn, requests. - Make sure to do this tutorial in the IPython notebook so that you get - the inline plots and easy documentation lookup. + Make sure to do this tutorial in a Jupyter notebook so that you get + the inline plots and easy documentation lookup. The shell command to open + one is simply `jupyter notebook`, then click New -> Python. """ # 1. Data acquisition ==== diff --git a/ru-ru/python3-ru.html.markdown b/ru-ru/python3-ru.html.markdown index 2b6b59a7..bf80fed2 100644 --- a/ru-ru/python3-ru.html.markdown +++ b/ru-ru/python3-ru.html.markdown @@ -106,6 +106,9 @@ False or True #=> True # И строки тоже могут складываться! Хотя лучше не злоупотребляйте этим. "Привет " + "мир!" #=> "Привет мир!" +# Строки можно умножать. +"aa" * 4 #=> "aaaaaaaa" + # Со строкой можно работать, как со списком символов "Это строка"[0] #=> 'Э' diff --git a/solidity.html.markdown b/solidity.html.markdown index c1f910fd..a0f8cd40 100644 --- a/solidity.html.markdown +++ b/solidity.html.markdown @@ -37,8 +37,8 @@ features are typically marked, and subject to change. Pull requests welcome. // simple_bank.sol (note .sol extension) /* **** START EXAMPLE **** */ -// Declare the source file compiler version. -pragma solidity ^0.4.2; +// Declare the source file compiler version +pragma solidity ^0.4.19; // Start with Natspec comment (the three slashes) // used for documentation - and as descriptive data for UI elements/actions @@ -65,7 +65,7 @@ contract SimpleBank { // CapWords event LogDepositMade(address accountAddress, uint amount); // Constructor, can receive one or many variables here; only one allowed - function SimpleBank() { + function SimpleBank() public { // msg provides details about the message that's sent to the contract // msg.sender is contract caller (address of contract creator) owner = msg.sender; @@ -73,7 +73,11 @@ contract SimpleBank { // CapWords /// @notice Deposit ether into bank /// @return The balance of the user after the deposit is made - function deposit() public returns (uint) { + function deposit() public payable returns (uint) { + // Use 'require' to test user inputs, 'assert' for internal invariants + // Here we are making sure that there isn't an overflow issue + require((balances[msg.sender] + msg.value) >= balances[msg.sender]); + balances[msg.sender] += msg.value; // no "this." or "self." required with state variable // all values set to data type's initial value by default @@ -88,18 +92,17 @@ contract SimpleBank { // CapWords /// @param withdrawAmount amount you want to withdraw /// @return The balance remaining for the user function withdraw(uint withdrawAmount) public returns (uint remainingBal) { - if(balances[msg.sender] >= withdrawAmount) { - // Note the way we deduct the balance right away, before sending - due to - // the risk of a recursive call that allows the caller to request an amount greater - // than their balance - balances[msg.sender] -= withdrawAmount; - - if (!msg.sender.send(withdrawAmount)) { - // increment back only on fail, as may be sending to contract that - // has overridden 'send' on the receipt end - balances[msg.sender] += withdrawAmount; - } - } + require(withdrawAmount <= balances[msg.sender]); + + // Note the way we deduct the balance right away, before sending + // Every .transfer/.send from this contract can call an external function + // This may allow the caller to request an amount greater + // than their balance using a recursive call + // Aim to commit state before calling external functions, including .transfer/.send + balances[msg.sender] -= withdrawAmount; + + // this automatically throws on a failure, which means the updated balance is reverted + msg.sender.transfer(withdrawAmount); return balances[msg.sender]; } @@ -108,18 +111,9 @@ contract SimpleBank { // CapWords /// @return The balance of the user // 'constant' prevents function from editing state variables; // allows function to run locally/off blockchain - function balance() constant returns (uint) { + function balance() constant public returns (uint) { return balances[msg.sender]; } - - // Fallback function - Called if other functions don't match call or - // sent ether without data - // Typically, called when invalid data is sent - // Added so ether sent to this contract is reverted if the contract fails - // otherwise, the sender's money is transferred to contract - function () { - throw; // throw reverts state to before call - } } // ** END EXAMPLE ** @@ -137,6 +131,11 @@ int256 constant a = 8; // same effect as line above, here the 256 is explicit uint constant VERSION_ID = 0x123A1; // A hex constant // with 'constant', compiler replaces each occurrence with actual value +// All state variables (those outside a function) +// are by default 'internal' and accessible inside contract +// and in all contracts that inherit ONLY +// Need to explicitly set to 'public' to allow external contracts to access +int256 public a = 8; // For int and uint, can explicitly set space in steps of 8 up to 256 // e.g., int8, int16, int24 @@ -145,6 +144,12 @@ int64 c; uint248 e; // Be careful that you don't overflow, and protect against attacks that do +// For example, for an addition, you'd do: +uint256 c = a + b; +assert(c >= a); // assert tests for internal invariants; require is used for user inputs +// For more examples of common arithmetic issues, see Zeppelin's SafeMath library +// https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/math/SafeMath.sol + // No random functions built in, use other contracts for randomness @@ -165,14 +170,14 @@ address public owner; // a getter is automatically created, but NOT a setter // All addresses can be sent ether -owner.send(SOME_BALANCE); // returns false on failure -if (owner.send) {} // REMEMBER: wrap in 'if', as contract addresses have +owner.transfer(SOME_BALANCE); // fails and reverts on failure + +// Can also do a lower level .send call, which returns a false if it failed +if (owner.send) {} // REMEMBER: wrap send in 'if', as contract addresses have // functions executed on send and these can fail // Also, make sure to deduct balances BEFORE attempting a send, as there is a risk of a recursive // call that can drain the contract -// can override send by defining your own - // Can check balance owner.balance; // the balance of the owner (user or contract) @@ -213,7 +218,7 @@ uint x = 5; // Destructuring/Tuples -(x, y) = (2, 7); // assign/swap multiple value +(x, y) = (2, 7); // assign/swap multiple values // 2. DATA STRUCTURES @@ -250,7 +255,7 @@ delete balances; // sets all elements to 0 // mapping, without knowing source keys - can build data structure // on top to do this -// Structs and enums +// Structs struct Bank { address owner; uint balance; @@ -273,7 +278,7 @@ state = State.Created; // enums can be explicitly converted to ints uint createdState = uint(State.Created); // 0 -// Data locations: Memory vs. storage vs. stack - all complex types (arrays, +// 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 @@ -292,13 +297,13 @@ uint createdState = uint(State.Created); // 0 // 4. Global Variables of note // ** this ** this; // address of contract -// often used at end of contract life to send remaining balance to party +// often used at end of contract life to transfer remaining balance to party this.balance; this.someFunction(); // calls func externally via call, not via internal jump // ** msg - Current message received by the contract ** ** msg.sender; // address of sender -msg.value; // amount of ether provided to this contract in wei +msg.value; // amount of ether provided to this contract in wei, the function should be marked "payable" msg.data; // bytes, complete call data msg.gas; // remaining gas @@ -308,6 +313,8 @@ tx.gasprice; // gas price of the transaction // ** block - Information about current block ** now; // current time (approximately), alias for block.timestamp (uses Unix time) +// Note that this can be manipulated by miners, so use carefully + block.number; // current block number block.difficulty; // current block difficulty block.blockhash(1); // returns bytes32, only works for most recent 256 blocks @@ -334,9 +341,10 @@ function increment(uint x, uint y) returns (uint x, uint y) { // Call previous functon uint (a,b) = increment(1,1); -// 'constant' indicates that function does not/cannot change persistent vars +// 'constant' (alias for 'view') +// indicates that function does not/cannot change persistent vars // Constant function execute locally, not on blockchain -uint y; +uint y = 1; function increment(uint x) constant returns (uint x) { x += 1; @@ -344,13 +352,21 @@ function increment(uint x) constant returns (uint x) { // y is a state variable, and can't be changed in a constant function } +// 'pure' is more strict than 'constant', and does not +// even allow reading of state vars +// The exact rules are more complicated, so see more about +// constant/pure: +// http://solidity.readthedocs.io/en/develop/contracts.html#view-functions + // 'Function Visibility specifiers' // These can be placed where 'constant' is, including: -// public - visible externally and internally (default) -// external +// public - visible externally and internally (default for function) +// external - only visible externally (including a call made with this.) // private - only visible in the current contract // internal - only visible in current contract, and those deriving from it +// Generally, a good idea to mark each function explicitly + // Functions hoisted - and can assign a function to a variable function a() { var z = b; @@ -361,8 +377,15 @@ function b() { } +// All functions that receive ether must be marked 'payable' +function depositEther() public payable { + balances[msg.sender] += msg.value; +} + // Prefer loops to recursion (max call stack depth is 1024) +// Also, don't setup loops that you haven't bounded, +// as this can hit the gas limit // B. Events // Events are notify external parties; easy to search and @@ -378,7 +401,8 @@ event LogSent(address indexed from, address indexed to, uint amount); // note ca // Call Sent(from, to, amount); -// For an external party (a contract or external entity), to watch: +// For an external party (a contract or external entity), to watch using +// the Web3 Javascript library: Coin.Sent().watch({}, '', function(error, result) { if (!error) { console.log("Coin transfer: " + result.args.amount + @@ -398,10 +422,10 @@ Coin.Sent().watch({}, '', function(error, result) { // '_' (underscore) often included as last line in body, and indicates // function being called should be placed there -modifier onlyAfter(uint _time) { if (now <= _time) throw; _ } -modifier onlyOwner { if (msg.sender == owner) _ } +modifier onlyAfter(uint _time) { require (now >= _time); _; } +modifier onlyOwner { require(msg.sender == owner) _; } // commonly used with state machines -modifier onlyIfState (State currState) { if (currState != State.A) _ } +modifier onlyIfStateA (State currState) { require(currState == State.A) _; } // Append right after function declaration function changeOwner(newOwner) @@ -415,12 +439,10 @@ onlyIfState(State.A) // underscore can be included before end of body, // but explicitly returning will skip, so use carefully modifier checkValue(uint amount) { - _ + _; if (msg.value > amount) { uint amountToRefund = amount - msg.value; - if (!msg.sender.send(amountToRefund)) { - throw; - } + msg.sender.transfer(amountToRefund); } } @@ -437,22 +459,21 @@ modifier checkValue(uint amount) { // amount of gas for a block of code - and will fail if that is exceeded // For example: for(uint x = 0; x < refundAddressList.length; x++) { - if (!refundAddressList[x].send(SOME_AMOUNT)) { - throw; - } + refundAddressList[x].transfer(SOME_AMOUNT); } // Two errors above: -// 1. A failure on send stops the loop from completing, tying up money +// 1. A failure on transfer stops the loop from completing, tying up money // 2. This loop could be arbitrarily long (based on the amount of users who need refunds), and // therefore may always fail as it exceeds the max gas for a block // Instead, you should let people withdraw individually from their subaccount, and mark withdrawn +// e.g., favor pull payments over push payments // 7. OBJECTS/CONTRACTS // A. Calling external contract -contract infoFeed { +contract InfoFeed { function info() returns (uint ret) { return 42; } } @@ -502,23 +523,10 @@ function someAbstractFunction(uint x); import "filename"; import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol"; -// Importing under active development -// Cannot currently be done at command line - // 8. OTHER KEYWORDS -// A. Throwing -// Throwing -throw; // reverts unused money to sender, state is reverted -// Can't currently catch - -// Common design pattern is: -if (!addr.send(123)) { - throw; -} - -// B. Selfdestruct +// A. Selfdestruct // selfdestruct current contract, sending funds to address (often creator) selfdestruct(SOME_ADDRESS); @@ -543,7 +551,7 @@ function remove() { // that is private needs to be obfuscated (e.g., hashed w/secret) // Steps: 1. Commit to something, 2. Reveal commitment -sha3("some_bid_amount", "some secret"); // commit +keccak256("some_bid_amount", "some secret"); // commit // call contract's reveal function in the future // showing bid plus secret that hashes to SHA3 @@ -617,6 +625,7 @@ contract SomeOracle { // ** START EXAMPLE ** // CrowdFunder.sol +pragma solidity ^0.4.19; /// @title CrowdFunder /// @author nemild @@ -650,22 +659,20 @@ contract CrowdFunder { event LogWinnerPaid(address winnerAddress); modifier inState(State _state) { - if (state != _state) throw; - _ + require(state == _state); + _; } modifier isCreator() { - if (msg.sender != creator) throw; - _ + require(msg.sender == creator); + _; } - // Wait 6 months after final contract state before allowing contract destruction + // Wait 24 weeks after final contract state before allowing contract destruction modifier atEndOfLifecycle() { - if(!((state == State.ExpiredRefund || state == State.Successful) && - completeAt + 6 months < now)) { - throw; - } - _ + require(((state == State.ExpiredRefund || state == State.Successful) && + completeAt + 24 weeks < now)); + _; } function CrowdFunder( @@ -673,6 +680,7 @@ contract CrowdFunder { string _campaignUrl, address _fundRecipient, uint _minimumToRaise) + public { creator = msg.sender; fundRecipient = _fundRecipient; @@ -683,7 +691,9 @@ contract CrowdFunder { function contribute() public + payable inState(State.Fundraising) + returns(uint256 id) { contributions.push( Contribution({ @@ -699,7 +709,9 @@ contract CrowdFunder { return contributions.length - 1; // return id } - function checkIfFundingCompleteOrExpired() { + function checkIfFundingCompleteOrExpired() + public + { if (totalRaised > minimumToRaise) { state = State.Successful; payOut(); @@ -715,31 +727,23 @@ contract CrowdFunder { public inState(State.Successful) { - if(!fundRecipient.send(this.balance)) { - throw; - } - - + fundRecipient.transfer(this.balance); LogWinnerPaid(fundRecipient); } - function getRefund(id) - public + function getRefund(uint256 id) inState(State.ExpiredRefund) + public + returns(bool) { - if (contributions.length <= id || id < 0 || contributions[id].amount == 0 ) { - throw; - } + require(contributions.length > id && id >= 0 && contributions[id].amount != 0 ); - uint amountToRefund = contributions[id].amount; + uint256 amountToRefund = contributions[id].amount; contributions[id].amount = 0; - if(!contributions[id].contributor.send(amountToSend)) { - contributions[id].amount = amountToSend; - return false; - } + contributions[id].contributor.transfer(amountToRefund); - return true; + return true; } function removeContract() @@ -750,8 +754,6 @@ contract CrowdFunder { selfdestruct(msg.sender); // creator gets all money that hasn't be claimed } - - function () { throw; } } // ** END EXAMPLE ** @@ -798,6 +800,7 @@ someContractAddress.callcode('function_name'); // 13. 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 @@ -825,11 +828,16 @@ someContractAddress.callcode('function_name'); ## Additional resources - [Solidity Docs](https://solidity.readthedocs.org/en/latest/) +- [Smart Contract Best Practices](https://github.com/ConsenSys/smart-contract-best-practices) - [Solidity Style Guide](https://ethereum.github.io/solidity//docs/style-guide/): Ethereum's style guide is heavily derived from Python's [pep8](https://www.python.org/dev/peps/pep-0008/) style guide. -- [Browser-based Solidity Editor](http://chriseth.github.io/browser-solidity/) +- [EthFiddle - The JsFiddle for Solidity](https://ethfiddle.com/) +- [Browser-based Solidity Editor](https://remix.ethereum.org/) - [Gitter Solidity Chat room](https://gitter.im/ethereum/solidity) - [Modular design strategies for Ethereum Contracts](https://docs.erisindustries.com/tutorials/solidity/) +## Important libraries +- [Zeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/): Libraries that provide common contract patterns (crowdfuding, safemath, etc) + ## Sample contracts - [Dapp Bin](https://github.com/ethereum/dapp-bin) - [Solidity Baby Step Contracts](https://github.com/fivedogit/solidity-baby-steps/tree/master/contracts) @@ -841,9 +849,6 @@ someContractAddress.callcode('function_name'); - [Smart Contract Security](https://blog.ethereum.org/2016/06/10/smart-contract-security/) - [Hacking Distributed Blog](http://hackingdistributed.com/) -## Information purposefully excluded -- Libraries - ## Style - Python's [PEP8](https://www.python.org/dev/peps/pep-0008/) is used as the baseline style guide, including its general philosophy diff --git a/typescript.html.markdown b/typescript.html.markdown index 10f01ebc..acc258b4 100644 --- a/typescript.html.markdown +++ b/typescript.html.markdown @@ -29,7 +29,7 @@ let notSure: any = 4; notSure = "maybe a string instead"; notSure = false; // okay, definitely a boolean -// Use const keyword for constant variables +// Use const keyword for constants const numLivesForCat = 9; numLivesForCat = 1; // Error diff --git a/yaml.html.markdown b/yaml.html.markdown index 3b32a069..52658453 100644 --- a/yaml.html.markdown +++ b/yaml.html.markdown @@ -2,8 +2,8 @@ language: yaml filename: learnyaml.yaml contributors: - - ["Adam Brenecki", "https://github.com/adambrenecki"] - - ["Suhas SG", "https://github.com/jargnar"] +- [Adam Brenecki, 'https://github.com/adambrenecki'] +- [Suhas SG, 'https://github.com/jargnar'] --- YAML is a data serialisation language designed to be directly writable and @@ -11,7 +11,7 @@ readable by humans. It's a strict superset of JSON, with the addition of syntactically significant newlines and indentation, like Python. Unlike Python, however, -YAML doesn't allow literal tab characters at all. +YAML doesn't allow literal tab characters for indentation. ```yaml # Comments in YAML look like this. @@ -32,8 +32,10 @@ boolean: true null_value: null key with spaces: value # Notice that strings don't need to be quoted. However, they can be. -however: "A string, enclosed in quotes." -"Keys can be quoted too.": "Useful if you want to put a ':' in your key." +however: 'A string, enclosed in quotes.' +'Keys can be quoted too.': "Useful if you want to put a ':' in your key." +single quotes: 'have ''one'' escape pattern' +double quotes: "have many: \", \0, \t, \u263A, \x0d\x0a == \r\n, and more." # Multiple-line strings can be written either as a 'literal block' (using |), # or a 'folded block' (using '>'). @@ -59,12 +61,12 @@ folded_style: > # COLLECTION TYPES # #################### -# Nesting is achieved by indentation. +# Nesting uses indentation. 2 space indent is preferred (but not required). a_nested_map: - key: value - another_key: Another Value - another_nested_map: - hello: hello + key: value + another_key: Another Value + another_nested_map: + hello: hello # Maps don't have to have string keys. 0.25: a float key @@ -72,8 +74,8 @@ a_nested_map: # Keys can also be complex, like multi-line objects # We use ? followed by a space to indicate the start of a complex key. ? | - This is a key - that has multiple lines + This is a key + that has multiple lines : and this is its value # YAML also allows mapping between sequences with the complex key syntax @@ -83,22 +85,26 @@ a_nested_map: - Real Madrid : [ 2001-01-01, 2002-02-02 ] -# Sequences (equivalent to lists or arrays) look like this: +# Sequences (equivalent to lists or arrays) look like this +# (note that the '-' counts as indentation): a_sequence: - - Item 1 - - Item 2 - - 0.5 # sequences can contain disparate types. - - Item 4 - - key: value - another_key: another_value - - - - This is a sequence - - inside another sequence +- Item 1 +- Item 2 +- 0.5 # sequences can contain disparate types. +- Item 4 +- key: value + another_key: another_value +- + - This is a sequence + - inside another sequence +- - - Nested sequence indicators + - can be collapsed # Since YAML is a superset of JSON, you can also write JSON-style maps and # sequences: json_map: {"key": "value"} json_seq: [3, 2, 1, "takeoff"] +and quotes are optional: {key: [3, 2, 1, takeoff]} ####################### # EXTRA YAML FEATURES # @@ -111,15 +117,15 @@ other_anchor: *anchor_name # Anchors can be used to duplicate/inherit properties base: &base - name: Everyone has same name + name: Everyone has same name foo: &foo - <<: *base - age: 10 + <<: *base + age: 10 bar: &bar - <<: *base - age: 20 + <<: *base + age: 20 # foo and bar would also have name: Everyone has same name @@ -147,22 +153,23 @@ date: 2002-12-14 # The !!binary tag indicates that a string is actually a base64-encoded # representation of a binary blob. gif_file: !!binary | - R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 - OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ - +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC - AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= + R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 + OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ + +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC + AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= # YAML also has a set type, which looks like this: set: - ? item1 - ? item2 - ? item3 + ? item1 + ? item2 + ? item3 +or: {item1, item2, item3} # Like Python, sets are just maps with null values; the above is equivalent to: set2: - item1: null - item2: null - item3: null + item1: null + item2: null + item3: null ``` ### More Resources diff --git a/zh-cn/javascript-cn.html.markdown b/zh-cn/javascript-cn.html.markdown index bdef0099..360f7c65 100644 --- a/zh-cn/javascript-cn.html.markdown +++ b/zh-cn/javascript-cn.html.markdown @@ -12,12 +12,9 @@ translators: lang: zh-cn --- -Javascript于1995年由网景公司的Brendan Eich发明。 -最初发明的目的是作为一个简单的网站脚本语言,来作为 -复杂网站应用java的补充。但由于它与网页结合度很高并且由浏览器内置支持, -所以javascript变得比java在前端更为流行了。 +Javascript 于 1995 年由网景公司的 Brendan Eich 发明。最初它作为一种简单的,用于开发网站的脚本语言而被发明出来,是用于开发复杂网站的 Java 的补充。但由于它与网页结合度很高并且在浏览器中得到内置的支持,所以在网页前端领域 Javascript 变得比 Java 更流行了。 -不过 JavaScript 可不仅仅只用于浏览器: Node.js,一个基于Google Chrome V8引擎的独立运行时环境,也越来越流行。 +不过,Javascript 不仅用于网页浏览器,一个名为 Node.js 的项目提供了面向 Google Chrome V8 引擎的独立运行时环境,它正在变得越来越流行。 很欢迎来自您的反馈,您可以通过下列方式联系到我: [@adambrenecki](https://twitter.com/adambrenecki), 或者 diff --git a/zh-cn/kotlin-cn.html.markdown b/zh-cn/kotlin-cn.html.markdown index 5d655029..f6dcd847 100644 --- a/zh-cn/kotlin-cn.html.markdown +++ b/zh-cn/kotlin-cn.html.markdown @@ -22,7 +22,7 @@ package com.learnxinyminutes.kotlin /* Kotlin程序的入口点是一个"main"函数 -该函数传递一个包含任何命令行参数的数组。 +该函数传递一个包含所有命令行参数的数组。 */ fun main(args: Array<String>) { /* @@ -67,10 +67,10 @@ fun helloWorld(val name : String) { 模板表达式从一个美元符号($)开始。 */ val fooTemplateString = "$fooString has ${fooString.length} characters" - println(fooTemplateString) + println(fooTemplateString) // => 输出 My String Is Here! has 18 characters /* - 当某个变量的值可以为 null 的时候,我们必须被明确指定它是可为空的。 + 当某个变量的值可以为 null 的时候,我们必须明确指定它是可为空的。 在变量声明处的类型后面加上?来标识它是可为空的。 我们可以用?.操作符来访问可为空的变量。 我们可以用?:操作符来指定一个在变量为空时使用的替代值。 @@ -96,24 +96,24 @@ fun helloWorld(val name : String) { println(hello()) // => Hello, world! /* - 用"vararg"关键字来修饰一个函数的参数来允许可变参数传递给该函数 + 函数的可变参数可使用 "vararg" 关键字来修饰 */ fun varargExample(vararg names: Int) { println("Argument has ${names.size} elements") } - varargExample() // => Argument has 0 elements - varargExample(1) // => Argument has 1 elements - varargExample(1, 2, 3) // => Argument has 3 elements + varargExample() // => 传入 0 个参数 + varargExample(1) // => 传入 1 个参数 + varargExample(1, 2, 3) // => 传入 3 个参数 /* - 当函数只包含一个单独的表达式时,大括号可以被省略。 - 函数体可以被指定在一个=符号后面。 + 当函数只包含一个单独的表达式时,大括号可以省略。 + 函数体可以写在一个=符号后面。 */ fun odd(x: Int): Boolean = x % 2 == 1 println(odd(6)) // => false println(odd(7)) // => true - // 如果返回值类型可以被推断,那么我们不需要指定它。 + // 如果返回值类型可以推断,那么我们不需要指定它。 fun even(x: Int) = x % 2 == 0 println(even(6)) // => true println(even(7)) // => false @@ -122,15 +122,14 @@ fun helloWorld(val name : String) { fun not(f: (Int) -> Boolean) : (Int) -> Boolean { return {n -> !f.invoke(n)} } - // 命名函数可以用::运算符被指定为参数。 + // 普通函数可以用::运算符传入引用作为函数参数。 val notOdd = not(::odd) val notEven = not(::even) - // 匿名函数可以被指定为参数。 + // lambda 表达式可以直接作为参数传递。 val notZero = not {n -> n == 0} /* - 如果一个匿名函数只有一个参数 - 那么它的声明可以被省略(连同->)。 - 这个参数的名字是"it"。 + 如果一个 lambda 表达式只有一个参数 + 那么它的声明可以省略(连同->),内部以 "it" 引用。 */ val notPositive = not {it > 0} for (i in 0..4) { @@ -152,7 +151,7 @@ fun helloWorld(val name : String) { 注意,Kotlin没有"new"关键字。 */ val fooExampleClass = ExampleClass(7) - // 可以使用一个点号来调用成员函数。 + // 可以使用一个点号来调用成员方法。 println(fooExampleClass.memberFunction(4)) // => 11 /* 如果使用"infix"关键字来标记一个函数 @@ -162,7 +161,7 @@ fun helloWorld(val name : String) { /* 数据类是创建只包含数据的类的一个简洁的方法。 - "hashCode"、"equals"和"toString"方法将被自动生成。 + "hashCode"、"equals"和"toString"方法将自动生成。 */ data class DataClassExample (val x: Int, val y: Int, val z: Int) val fooData = DataClassExample(1, 2, 4) diff --git a/zh-cn/make-cn.html.markdown b/zh-cn/make-cn.html.markdown new file mode 100644 index 00000000..4cdf1e63 --- /dev/null +++ b/zh-cn/make-cn.html.markdown @@ -0,0 +1,262 @@ +--- +language: make +contributors: +- ["Robert Steed", "https://github.com/robochat"] +- ["Jichao Ouyang", "https://github.com/jcouyang"] +translators: +- ["Jichao Ouyang", "https://github.com/jcouyang"] +filename: Makefile-cn +lang: zh-cn +--- + +Makefile 用于定义如何创建目标文件, 比如如何从源码到可执行文件. 创建这一工具的目标是 +减少不必要的编译或者任务.是传说中的 Stuart Feldman 在 1976 年花了一个周末写出来的, +而今仍然使用广泛, 特别是在 Unix 和 Linux 系统上. + +虽然每个语言可能都有相应的或多或少提供 make 的功能, 比如 ruby 的 rake, node 的 gulp, broccoli +, scala 的 sbt 等等. 但是 make 的简洁与高效, 和只做一件事并做到极致的风格, 使其至今仍是无可替代的, +甚至与其他构建工具一起使用也并无冲突. + +尽管有许多的分支和变体, 这篇文章针对是标准的 GNU make. + +```make +# 这行表示注释 + +# 文件名一定要交 Makefile, 大小写区分, 使用 `make <target>` 生成 target +# 如果想要取别的名字, 可以用 `make -f "filename" <target>`. + +# 重要的事情 - 只认识 TAB, 空格是不认的, 但是在 GNU Make 3.82 之后, 可以通过 +# 设置参数 .RECIPEPREFIX 进行修改 + +#----------------------------------------------------------------------- +# 初级 +#----------------------------------------------------------------------- + +# 创建一个 target 的规则非常简单 +# targets : prerequisites +# recipe +# … +# prerequisites(依赖) 是可选的, recipe(做法) 也可以多个或者不给. + +# 下面这个任务没有给 prerequisites, 只会在目标文件 file0.txt 文件不存在是跑 +file0.txt: + echo "foo" > file0.txt + # 试试 `make file0.txt` + # 或者直接 `make`, 因为第一个任务是默认任务. + # 注意: 即使是这些注释, 如果前面有 TAB, 也会发送给 shell, 注意看 `make file0.txt` 输出 + +# 如果提供 prerequisites, 则只有 prerequisites 比 target 新时会执行 +# 比如下面这个任务只有当 file1.txt 比 file0.txt 新时才会执行. +file1.txt: file0.txt + cat file0.txt > file1.txt + # 这里跟shell里的命令式一毛一样的. + @cat file0.txt >> file1.txt + # @ 不会把命令往 stdout 打印. + -@echo 'hello' + # - 意思是发生错误了也没关系. + # 试试 `make file1.txt` 吧. + +# targets 和 prerequisites 都可以是多个, 以空格分割 +file2.txt file3.txt: file0.txt file1.txt + touch file2.txt + touch file3.txt + +# 如果声明重复的 target, make 会给一个 warning, 后面会覆盖前面的 +# 比如重复定义 file2.txt 会得到这样的 warning +# Makefile:46: warning: overriding commands for target `file2.txt' +# Makefile:40: warning: ignoring old commands for target `file2.txt' +file2.txt: file0.txt + touch file2.txt + +# 但是如果不定义任何 recipe, 就不会冲突, 只是多了依赖关系 +file2.txt: file0.txt file3.txt + +#----------------------------------------------------------------------- +# Phony(假的) Targets +#----------------------------------------------------------------------- + +# phony targets 意思是 tagets 并不是文件, 可以想象成一个任务的名字而已. +# 因为不是文件, 无法比对是否有更新, 所以每次make都会执行. +all: maker process + +# 依赖于 phony target 的 target 也会每次 make 都执行, 即使 target 是文件 +ex0.txt ex1.txt: maker + +# target 的声明顺序并不重要, 比如上面的 all 的依赖 maker 现在才声明 +maker: + touch ex0.txt ex1.txt + +# 如果定义的 phony target 与文件名重名, 可以用 .PHONY 显示的指明哪些 targets 是 phony +.PHONY: all maker process +# This is a special target. There are several others. + +# 常用的 phony target 有: all clean install ... + +#----------------------------------------------------------------------- +# 变量与通配符 +#----------------------------------------------------------------------- + +process: file*.txt | dir/a.foo.b # 可以用通配符匹配多个文件作为prerequisites + @echo $^ # $^ 是 prerequisites + @echo $@ # $@ 代表 target, 如果 target 为多个, $@ 代表当前执行的那个 + @echo $< # $< prerequisite 中的第一个 + @echo $? # $? 需要更新的 prerequisite 文件列表 + @echo $+ # $+ 所有依赖, 包括重复的 + @echo $| # $| 竖线后面的 order-only prerequisites + +a.%.b: + @echo $* # $* match 的target % 那部分, 包括路径, 比如 `make dir/a.foo.b` 会打出 `dir/foo` + +# 即便分开定义依赖, $^ 依然能拿到 +process: ex1.txt file0.txt +# 非常智能的, ex1.txt 会被找到, file0.txt 会被去重. + +#----------------------------------------------------------------------- +# 模式匹配 +#----------------------------------------------------------------------- + +# 可以让 make 知道如何转换某些文件到别格式 +# 比如 从 svg 到 png +%.png: %.svg + inkscape --export-png $^ + +# 一旦有需要 foo.png 这个任务就会运行 + +# 路径会被忽略, 所以上面的 target 能匹配所有 png +# 但是如果加了路径, make 会找到最接近的匹配, 如果 +# make small/foo.png (在这之前要先有 small/foo.svg 这个文件) +# 则会匹配下面这个规则 +small/%.png: %.svg + inkscape --export-png --export-dpi 30 $^ + +%.png: %.svg + @echo 重复定义会覆盖前面的, 现在 inkscape 没用了 + +# make 已经有一些内置的规则, 比如从 *.c 到 *.o + +#----------------------------------------------------------------------- +# 变量 +#----------------------------------------------------------------------- +# 其实是宏 macro + +# 变量都是字符串类型, 下面这俩是一样一样的 + +name = Ted +name2="Sarah" + +echo: + @echo $(name) + @echo ${name2} + @echo $name # 这个会被蠢蠢的解析成 $(n)ame. + @echo \"$(name3)\" # 为声明的变量或扩展成空字符串. + @echo $(name4) + @echo $(name5) +# 你可以通过4种方式设置变量. +# 按以下顺序由高到低: +# 1: 命令行参数. 比如试试 `make echo name3=JICHAO` +# 2: Makefile 里面的 +# 3: shell 中的环境变量 +# 4: make 预设的一些变量 + +name4 ?= Jean +# 问号意思是如果 name4 被设置过了, 就不设置了. + +override name5 = David +# 用 override 可以防止命令行参数设置的覆盖 + +name4 +=grey +# 用加号可以连接 (中间用空格分割). + +# 在依赖的地方设置变量 +echo: name2 = Sara2 + +# 还有一些内置的变量 +echo_inbuilt: + echo $(CC) + echo ${CXX)} + echo $(FC) + echo ${CFLAGS)} + echo $(CPPFLAGS) + echo ${CXXFLAGS} + echo $(LDFLAGS) + echo ${LDLIBS} + +#----------------------------------------------------------------------- +# 变量 2 +#----------------------------------------------------------------------- + +# 加个冒号可以声明 Simply expanded variables 即时扩展变量, 即只在声明时扩展一次 +# 之前的等号声明时 recursively expanded 递归扩展 + +var := hello +var2 := $(var) hello + +# 这些变量会在其引用的顺序求值 +# 比如 var3 声明时找不到 var4, var3 会扩展成 `and good luck` +var3 := $(var4) and good luck +# 但是一般的变量会在调用时递归扩展, 先扩展 var5, 再扩展 var4, 所以是正常的 +var5 = $(var4) and good luck +var4 := good night + +echoSEV: + @echo $(var) + @echo $(var2) + @echo $(var3) + @echo $(var4) + @echo $(var5) + +#----------------------------------------------------------------------- +# 函数 +#----------------------------------------------------------------------- + +# make 自带了一些函数. +# wildcard 会将后面的通配符变成一串文件路径 +all_markdown: + @echo $(wildcard *.markdown) +# patsubst 可以做替换, 比如下面会把所有 markdown +# 后缀的文件重命名为 md 后缀 +substitue: * + @echo $(patsubst %.markdown,%.md,$* $^) + +# 函数调用格式是 $(func arg0,arg1,arg2...) + +# 试试 +ls: * + @echo $(filter %.txt, $^) + @echo $(notdir $^) + @echo $(join $(dir $^),$(notdir $^)) + +#----------------------------------------------------------------------- +# Directives +#----------------------------------------------------------------------- + +# 可以用 include 引入别的 Makefile 文件 +# include foo.mk + +sport = tennis +# 一些逻辑语句 if else 什么的, 顶个写 +report: +ifeq ($(sport),tennis) + @echo 'game, set, match' +else + @echo "They think it's all over; it is now" +endif + +# 还有 ifneq, ifdef, ifndef + +foo = true + +# 不只是 recipe, 还可以写在外面哟 +ifdef $(foo) +bar = 'bar' +endif + +hellobar: + @echo bar +``` + +### 资源 + ++ GNU Make 官方文档 [HTML](https://www.gnu.org/software/make/manual/) [PDF](https://www.gnu.org/software/make/manual/make.pdf) ++ [software carpentry tutorial](http://swcarpentry.github.io/make-novice/) ++ learn C the hard way [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html) |