diff options
42 files changed, 2916 insertions, 526 deletions
diff --git a/asymptotic-notation.html.markdown b/asymptotic-notation.html.markdown index 6a6df968..a1dfe9e1 100644 --- a/asymptotic-notation.html.markdown +++ b/asymptotic-notation.html.markdown @@ -155,7 +155,7 @@ Small-o, commonly written as **o**, is an Asymptotic Notation to denote the upper bound (that is not asymptotically tight) on the growth rate of runtime of an algorithm. -`f(n)` is o(g(n)), if for some real constants c (c > 0) and n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` is < `c g(n)` +`f(n)` is o(g(n)), if for all real constants c (c > 0) and n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` is < `c g(n)` for every input size n (n > n<sub>0</sub>). The definitions of O-notation and o-notation are similar. The main difference @@ -168,7 +168,7 @@ Small-omega, commonly written as **ω**, is an Asymptotic Notation to denote the lower bound (that is not asymptotically tight) on the growth rate of runtime of an algorithm. -`f(n)` is ω(g(n)), if for some real constants c (c > 0) and n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` is > `c g(n)` +`f(n)` is ω(g(n)), if for all real constants c (c > 0) and n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` is > `c g(n)` for every input size n (n > n<sub>0</sub>). The definitions of Ω-notation and ω-notation are similar. The main difference diff --git a/awk.html.markdown b/awk.html.markdown index e3ea6318..de26c0a1 100644 --- a/awk.html.markdown +++ b/awk.html.markdown @@ -161,7 +161,7 @@ function arithmetic_functions(a, b, c, d) { # Most AWK implementations have some standard trig functions localvar = sin(a) localvar = cos(a) - localvar = atan2(a, b) # arc tangent of b / a + localvar = atan2(b, a) # arc tangent of b / a # And logarithmic stuff localvar = exp(a) diff --git a/bash.html.markdown b/bash.html.markdown index 3f3e49eb..d1e6bf25 100644 --- a/bash.html.markdown +++ b/bash.html.markdown @@ -74,7 +74,7 @@ echo ${Variable/Some/A} # => A string # Substring from a variable Length=7 -echo ${Variable:0:Length} # => Some st +echo ${Variable:0:$Length} # => Some st # This will return only the first 7 characters of the value # Default value for variable diff --git a/chapel.html.markdown b/chapel.html.markdown index 9190f462..354cd832 100644 --- a/chapel.html.markdown +++ b/chapel.html.markdown @@ -100,7 +100,7 @@ writeln(varCmdLineArg, ", ", constCmdLineArg, ", ", paramCmdLineArg); // be made to alias a variable other than the variable it is initialized with. // Here, refToActual refers to actual. var actual = 10; -ref refToActual = actual; +ref refToActual = actual; writeln(actual, " == ", refToActual); // prints the same value actual = -123; // modify actual (which refToActual refers to) writeln(actual, " == ", refToActual); // prints the same value @@ -444,7 +444,7 @@ arrayFromLoop = [value in arrayFromLoop] value + 1; // Procedures -// Chapel procedures have similar syntax functions in other languages. +// Chapel procedures have similar syntax functions in other languages. proc fibonacci(n : int) : int { if n <= 1 then return n; return fibonacci(n-1) + fibonacci(n-2); @@ -893,7 +893,6 @@ foo(); // We can declare a main procedure, but all the code above main still gets // executed. proc main() { - writeln("PARALLELISM START"); // A begin statement will spin the body of that statement off // into one new task. @@ -1141,11 +1140,13 @@ to see if more topics have been added or more tutorials created. Your input, questions, and discoveries are important to the developers! ----------------------------------------------------------------------- -The Chapel language is still in-development (version 1.16.0), so there are +The Chapel language is still in active development, so there are occasional hiccups with performance and language features. The more information you give the Chapel development team about issues you encounter or features you -would like to see, the better the language becomes. Feel free to email the team -and other developers through the [sourceforge email lists](https://sourceforge.net/p/chapel/mailman). +would like to see, the better the language becomes. +There are several ways to interact with the developers: ++ [Gitter chat](https://gitter.im/chapel-lang/chapel) ++ [sourceforge email lists](https://sourceforge.net/p/chapel/mailman) If you're really interested in the development of the compiler or contributing to the project, [check out the master GitHub repository](https://github.com/chapel-lang/chapel). @@ -1154,12 +1155,14 @@ It is under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0) Installing the Compiler ----------------------- +[The Official Chapel documentation details how to download and compile the Chapel compiler.](https://chapel-lang.org/docs/usingchapel/QUICKSTART.html) + Chapel can be built and installed on your average 'nix machine (and cygwin). [Download the latest release version](https://github.com/chapel-lang/chapel/releases/) and it's as easy as - 1. `tar -xvf chapel-1.16.0.tar.gz` - 2. `cd chapel-1.16.0` + 1. `tar -xvf chapel-<VERSION>.tar.gz` + 2. `cd chapel-<VERSION>` 3. `source util/setchplenv.bash # or .sh or .csh or .fish` 4. `make` 5. `make check # optional` diff --git a/citron.html.markdown b/citron.html.markdown new file mode 100644 index 00000000..bd3c398c --- /dev/null +++ b/citron.html.markdown @@ -0,0 +1,212 @@ +--- +language: citron +filename: learncitron.ctr +contributors: + - ["AnotherTest", ""] +lang: en-us +--- +```ruby +# Comments start with a '#' +# All comments encompass a single line + +########################################### +## 1. Primitive Data types and Operators +########################################### + +# You have numbers +3. # 3 + +# Numbers are all doubles in interpreted mode + +# Mathematical operator precedence is not respected. +# binary 'operators' are evaluated in ltr order +1 + 1. # 2 +8 - 4. # 4 +10 + 2 * 3. # 36 + +# Division is always floating division +35 / 2 # 17.5. + +# Integer division is non-trivial, you may use floor +(35 / 2) floor # 17. + +# Booleans are primitives +True. +False. + +# Boolean messages +True not. # False +False not. # True +1 = 1. # True +1 !=: 1. # False +1 < 10. # True + +# Here, `not` is a unary message to the object `Boolean` +# Messages are comparable to instance method calls +# And they have three different forms: +# 1. Unary messages: Length > 1, and they take no arguments: + False not. +# 2. Binary Messages: Length = 1, and they take a single argument: + False & True. +# 3. Keyword messages: must have at least one ':', they take as many arguments +# as they have `:` s + False either: 1 or: 2. # 2 + +# Strings +'This is a string'. +'There are no character types exposed to the user'. +# "You cannot use double quotes for strings" <- Error + +# Strins can be summed +'Hello, ' + 'World!'. # 'Hello, World!' + +# Strings allow access to their characters +'This is a beautiful string' at: 0. # 'T' + +########################################### +## intermission: Basic Assignment +########################################### + +# You may assign values to the current scope: +var name is value. # assignes `value` into `name` + +# You may also assign values into the current object's namespace +my name is value. # assigns `value` into the current object's `name` property + +# Please note that these names are checked at compile (read parse if in interpreted mode) time +# but you may treat them as dynamic assignments anyway + +########################################### +## 2. Lists(Arrays?) and Tuples +########################################### + +# Arrays are allowed to have multiple types +Array new < 1 ; 2 ; 'string' ; Nil. # Array new < 1 ; 2 ; 'string' ; Nil + +# Tuples act like arrays, but are immutable. +# Any shenanigans degrade them to arrays, however +[1, 2, 'string']. # [1, 2, 'string'] + +# They can interoperate with arrays +[1, 'string'] + (Array new < 'wat'). # Array new < 1 ; 'string' ; 'wat' + +# Indexing into them +[1, 2, 3] at: 1. # 2 + +# Some array operations +var arr is Array new < 1 ; 2 ; 3. + +arr head. # 1 +arr tail. # Array new < 2 ; 3. +arr init. # Array new < 1 ; 2. +arr last. # 3 +arr push: 4. # Array new < 1 ; 2 ; 3 ; 4. +arr pop. # 4 +arr pop: 1. # 2, `arr` is rebound to Array new < 1 ; 3. + +# List comprehensions +[x * 2 + y,, arr, arr + [4, 5],, x > 1]. # Array ← 7 ; 9 ; 10 ; 11 +# fresh variable names are bound as they are encountered, +# so `x` is bound to the values in `arr` +# and `y` is bound to the values in `arr + [4, 5]` +# +# The general format is: [expr,, bindings*,, predicates*] + + +#################################### +## 3. Functions +#################################### + +# A simple function that takes two variables +var add is {:a:b ^a + b.}. + +# this function will resolve all its names except the formal arguments +# in the context it is called in. + +# Using the function +add applyTo: 3 and: 5. # 8 +add applyAll: [3, 5]. # 8 + +# Also a (customizable -- more on this later) pseudo-operator allows for a shorthand +# of function calls +# By default it is REF[args] + +add[3, 5]. # 8 + +# To customize this behaviour, you may simply use a compiler pragma: +#:callShorthand () + +# And then you may use the specified operator. +# Note that the allowed 'operator' can only be made of any of these: []{}() +# And you may mix-and-match (why would anyone do that?) + +add(3, 5). # 8 + +# You may also use functions as operators in the following way: + +3 `add` 5. # 8 +# This call binds as such: add[(3), 5] +# because the default fixity is left, and the default precedance is 1 + +# You may change the precedence/fixity of this operator with a pragma +#:declare infixr 1 add + +3 `add` 5. # 8 +# now this binds as such: add[3, (5)]. + +# There is another form of functions too +# So far, the functions were resolved in a dynamic fashion +# But a lexically scoped block is also possible +var sillyAdd is {\:x:y add[x,y].}. + +# In these blocks, you are not allowed to declare new variables +# Except with the use of Object::'letEqual:in:` +# And the last expression is implicitly returned. + +# You may also use a shorthand for lambda expressions +var mul is \:x:y x * y. + +# These capture the named bindings that are not present in their +# formal parameters, and retain them. (by ref) + +########################################### +## 5. Control Flow +########################################### + +# inline conditional-expressions +var citron is 1 = 1 either: 'awesome' or: 'awful'. # citron is 'awesome' + +# multiple lines is fine too +var citron is 1 = 1 + either: 'awesome' + or: 'awful'. + +# looping +10 times: {:x + Pen writeln: x. +}. # 10. -- side effect: 10 lines in stdout, with numbers 0 through 9 in them + +# Citron properly supports tail-call recursion in lexically scoped blocks +# So use those to your heart's desire + +# mapping most data structures is as simple as `fmap:` +[1, 2, 3, 4] fmap: \:x x + 1. # [2, 3, 4, 5] + +# You can use `foldl:accumulator:` to fold a list/tuple +[1, 2, 3, 4] foldl: (\:acc:x acc * 2 + x) accumulator: 4. # 90 + +# That expression is the same as +(2 * (2 * (2 * (2 * 4 + 1) + 2) + 3) + 4) + +################################### +## 6. IO +################################### + +# IO is quite simple +# With `Pen` being used for console output +# and Program::'input' and Program::'waitForInput' being used for console input + +Pen writeln: 'Hello, ocean!' # prints 'Hello, ocean!\n' to the terminal + +Pen writeln: Program waitForInput. # reads a line and prints it back +``` diff --git a/common-lisp.html.markdown b/common-lisp.html.markdown index e2cf62fb..76e7735b 100644 --- a/common-lisp.html.markdown +++ b/common-lisp.html.markdown @@ -16,7 +16,7 @@ popular and recent book is [Land of Lisp](http://landoflisp.com/). A new book ab -```common-lisp +```lisp ;;;----------------------------------------------------------------------------- ;;; 0. Syntax diff --git a/cs-cz/markdown.html.markdown b/cs-cz/markdown.html.markdown index 568e4343..35becf94 100644 --- a/cs-cz/markdown.html.markdown +++ b/cs-cz/markdown.html.markdown @@ -13,7 +13,7 @@ Markdown byl vytvořen Johnem Gruberem v roce 2004. Je zamýšlen jako lehce či a psatelná syntaxe, která je jednoduše převeditelná do HTML (a dnes i do mnoha dalších formátů) -```markdown +```md <!-- Markdown je nadstavba nad HTML, takže jakýkoliv kód HTML je validní Markdown, to znamená, že můžeme používat HTML elementy, třeba jako komentář, a nebudou ovlivněny parserem Markdownu. Avšak, pokud vytvoříte HTML element v diff --git a/cypher.html.markdown b/cypher.html.markdown index b7be544a..acd44733 100644 --- a/cypher.html.markdown +++ b/cypher.html.markdown @@ -16,19 +16,19 @@ Nodes **Represents a record in a graph.** -```()``` +`()` It's an empty *node*, to indicate that there is a *node*, but it's not relevant for the query. -```(n)``` +`(n)` It's a *node* referred by the variable **n**, reusable in the query. It begins with lowercase and uses camelCase. -```(p:Person)``` +`(p:Person)` You can add a *label* to your node, here **Person**. It's like a type / a class / a category. It begins with uppercase and uses camelCase. -```(p:Person:Manager)``` +`(p:Person:Manager)` A node can have many *labels*. -```(p:Person {name : 'Théo Gauchoux', age : 22})``` +`(p:Person {name : 'Théo Gauchoux', age : 22})` A node can have some *properties*, here **name** and **age**. It begins with lowercase and uses camelCase. The types allowed in properties : @@ -40,7 +40,7 @@ The types allowed in properties : *Warning : there isn't datetime property in Cypher ! You can use String with a specific pattern or a Numeric from a specific date.* -```p.name``` +`p.name` You can access to a property with the dot style. @@ -49,16 +49,16 @@ Relationships (or Edges) **Connects two nodes** -```[:KNOWS]``` +`[:KNOWS]` It's a *relationship* with the *label* **KNOWS**. It's a *label* as the node's label. It begins with uppercase and use UPPER_SNAKE_CASE. -```[k:KNOWS]``` +`[k:KNOWS]` The same *relationship*, referred by the variable **k**, reusable in the query, but it's not necessary. -```[k:KNOWS {since:2017}]``` +`[k:KNOWS {since:2017}]` The same *relationship*, with *properties* (like *node*), here **since**. -```[k:KNOWS*..4]``` +`[k:KNOWS*..4]` It's a structural information to use in a *path* (seen later). Here, **\*..4** says "Match the pattern, with the relationship **k** which be repeated between 1 and 4 times. @@ -67,16 +67,16 @@ Paths **The way to mix nodes and relationships.** -```(a:Person)-[:KNOWS]-(b:Person)``` +`(a:Person)-[:KNOWS]-(b:Person)` A path describing that **a** and **b** know each other. -```(a:Person)-[:MANAGES]->(b:Person)``` +`(a:Person)-[:MANAGES]->(b:Person)` A path can be directed. This path describes that **a** is the manager of **b**. -```(a:Person)-[:KNOWS]-(b:Person)-[:KNOWS]-(c:Person)``` +`(a:Person)-[:KNOWS]-(b:Person)-[:KNOWS]-(c:Person)` You can chain multiple relationships. This path describes the friend of a friend. -```(a:Person)-[:MANAGES]->(b:Person)-[:MANAGES]->(c:Person)``` +`(a:Person)-[:MANAGES]->(b:Person)-[:MANAGES]->(c:Person)` A chain can also be directed. This path describes that **a** is the boss of **b** and the big boss of **c**. Patterns often used (from Neo4j doc) : @@ -230,13 +230,13 @@ DELETE n, r Other useful clauses --- -```PROFILE``` +`PROFILE` Before a query, show the execution plan of it. -```COUNT(e)``` +`COUNT(e)` Count entities (nodes or relationships) matching **e**. -```LIMIT x``` +`LIMIT x` Limit the result to the x first results. diff --git a/es-es/awk-es.html.markdown b/es-es/awk-es.html.markdown index 307ba817..0516ea92 100644 --- a/es-es/awk-es.html.markdown +++ b/es-es/awk-es.html.markdown @@ -166,7 +166,7 @@ function arithmetic_functions(a, b, c, localvar) { # trigonométricas estándar localvar = sin(a) localvar = cos(a) - localvar = atan2(a, b) # arcotangente de b / a + localvar = atan2(b, a) # arcotangente de b / a # Y cosas logarítmicas localvar = exp(a) diff --git a/es-es/markdown-es.html.markdown b/es-es/markdown-es.html.markdown index 0505b4cb..e23a94ea 100644 --- a/es-es/markdown-es.html.markdown +++ b/es-es/markdown-es.html.markdown @@ -14,7 +14,7 @@ fácilmente a HTML (y, actualmente, otros formatos también). ¡Denme toda la retroalimentación que quieran! / ¡Sientanse en la libertad de hacer forks o pull requests! -```markdown +```md <!-- Markdown está basado en HTML, así que cualquier archivo HTML es Markdown válido, eso significa que podemos usar elementos HTML en Markdown como, por ejemplo, el comentario y no serán afectados por un parseador Markdown. Aún diff --git a/es-es/objective-c-es.html.markdown b/es-es/objective-c-es.html.markdown index bdbce524..26cd14d9 100644 --- a/es-es/objective-c-es.html.markdown +++ b/es-es/objective-c-es.html.markdown @@ -13,7 +13,7 @@ Objective C es el lenguaje de programación principal utilizado por Apple para l Es un lenguaje de programación para propósito general que le agrega al lenguaje de programación C una mensajería estilo "Smalltalk". -```objective_c +```objectivec // Los comentarios de una sola línea inician con // /* diff --git a/es-es/visualbasic-es.html.markdown b/es-es/visualbasic-es.html.markdown index c7f581c0..ca00626b 100644 --- a/es-es/visualbasic-es.html.markdown +++ b/es-es/visualbasic-es.html.markdown @@ -10,7 +10,7 @@ filename: learnvisualbasic-es.vb lang: es-es --- -```vb +``` Module Module1 Sub Main() diff --git a/fi-fi/markdown-fi.html.markdown b/fi-fi/markdown-fi.html.markdown index c5ee52b0..defc7100 100644 --- a/fi-fi/markdown-fi.html.markdown +++ b/fi-fi/markdown-fi.html.markdown @@ -10,7 +10,7 @@ lang: fi-fi John Gruber loi Markdownin vuona 2004. Sen tarkoitus on olla helposti luettava ja kirjoitettava syntaksi joka muuntuu helposti HTML:ksi (ja nyt myös moneksi muuksi formaatiksi). -```markdown +```md <!-- Jokainen HTML-tiedosto on pätevää Markdownia. Tämä tarkoittaa että voimme käyttää HTML-elementtejä Markdownissa, kuten kommentteja, ilman että markdown -jäsennin vaikuttaa niihin. Tästä johtuen et voi kuitenkaan käyttää markdownia diff --git a/fr-fr/jquery-fr.html.markdown b/fr-fr/jquery-fr.html.markdown index 1842e02b..aeddbd53 100644 --- a/fr-fr/jquery-fr.html.markdown +++ b/fr-fr/jquery-fr.html.markdown @@ -138,5 +138,5 @@ $('p').each(function() { }); -`` +``` diff --git a/fsharp.html.markdown b/fsharp.html.markdown index bbf477ba..dd85552d 100644 --- a/fsharp.html.markdown +++ b/fsharp.html.markdown @@ -306,7 +306,7 @@ module DataTypeExamples = // ------------------------------------ // Union types (aka variants) have a set of choices - // Only case can be valid at a time. + // Only one case can be valid at a time. // ------------------------------------ // Use "type" with bar/pipe to define a union type diff --git a/id-id/markdown.html.markdown b/id-id/markdown.html.markdown index 06ad1092..1ff1963b 100644 --- a/id-id/markdown.html.markdown +++ b/id-id/markdown.html.markdown @@ -13,7 +13,7 @@ Markdown dibuat oleh John Gruber pada tahun 2004. Tujuannya untuk menjadi syntax Beri masukan sebanyak-banyaknya! / Jangan sungkan untuk melakukan fork dan pull request! -```markdown +```md <!-- Markdown adalah superset dari HTML, jadi setiap berkas HTML adalah markdown yang valid, ini berarti kita dapat menggunakan elemen HTML dalam markdown, seperti elemen komentar, dan ia tidak akan terpengaruh parser markdown. Namun, jika Anda membuat diff --git a/it-it/markdown.html.markdown b/it-it/markdown.html.markdown index 44801747..11da81ec 100644 --- a/it-it/markdown.html.markdown +++ b/it-it/markdown.html.markdown @@ -28,7 +28,7 @@ Markdown varia nelle sue implementazioni da un parser all'altro. Questa guida ce ## Elementi HTML Markdown è un superset di HTML, quindi ogni file HTML è a sua volta un file Markdown valido. -```markdown +```md <!-- Questo significa che possiamo usare elementi di HTML in Markdown, come per esempio i commenti, e questi non saranno modificati dal parser di Markdown. State attenti però, se inserite un elemento HTML nel vostro file Markdown, non potrete usare la sua sintassi diff --git a/it-it/python3-it.html.markdown b/it-it/python3-it.html.markdown index 06ef9a5e..04f78cff 100644 --- a/it-it/python3-it.html.markdown +++ b/it-it/python3-it.html.markdown @@ -400,8 +400,8 @@ else: # Anche else è opzionale print("some_var è 10.") """ -I cicli for iterano sulle liste, cioé ripetono un codice per ogni elemento -# di una lista. +I cicli for iterano sulle liste, cioè ripetono un codice per ogni elemento +di una lista. Il seguente codice scriverà: cane è un mammifero gatto è un mammifero @@ -409,7 +409,7 @@ Il seguente codice scriverà: """ for animale in ["cane", "gatto", "topo"]: # Puoi usare format() per interpolare le stringhe formattate. - print("{} is a mammal".format(animal)) + print("{} è un mammifero".format(animale)) """ "range(numero)" restituisce una lista di numeri da zero al numero dato diff --git a/julia.html.markdown b/julia.html.markdown index 9e28452f..891a0a00 100644 --- a/julia.html.markdown +++ b/julia.html.markdown @@ -2,16 +2,17 @@ language: Julia contributors: - ["Leah Hanson", "http://leahhanson.us"] - - ["Pranit Bauva", "http://github.com/pranitbauva1997"] + - ["Pranit Bauva", "https://github.com/pranitbauva1997"] + - ["Daniel YC Lin", "https://github.com/dlintw"] filename: learnjulia.jl --- Julia is a new homoiconic functional language focused on technical computing. While having the full power of homoiconic macros, first-class functions, and low-level control, Julia is as easy to learn and use as Python. -This is based on Julia 0.4. +This is based on Julia 1.0.0 -```ruby +```julia # Single line comments start with a hash (pound) symbol. #= Multiline comments can be written @@ -26,38 +27,38 @@ This is based on Julia 0.4. # Everything in Julia is an expression. # There are several basic types of numbers. -3 # => 3 (Int64) -3.2 # => 3.2 (Float64) -2 + 1im # => 2 + 1im (Complex{Int64}) -2//3 # => 2//3 (Rational{Int64}) +3 # => 3 (Int64) +3.2 # => 3.2 (Float64) +2 + 1im # => 2 + 1im (Complex{Int64}) +2 // 3 # => 2 // 3 (Rational{Int64}) # All of the normal infix operators are available. -1 + 1 # => 2 -8 - 1 # => 7 -10 * 2 # => 20 -35 / 5 # => 7.0 -5 / 2 # => 2.5 # dividing an Int by an Int always results in a Float -div(5, 2) # => 2 # for a truncated result, use div -5 \ 35 # => 7.0 -2 ^ 2 # => 4 # power, not bitwise xor -12 % 10 # => 2 +1 + 1 # => 2 +8 - 1 # => 7 +10 * 2 # => 20 +35 / 5 # => 7.0 +5 / 2 # => 2.5 # dividing integers always results in a Float64 +div(5, 2) # => 2 # for a truncated result, use div +5 \ 35 # => 7.0 +2^2 # => 4 # power, not bitwise xor +12 % 10 # => 2 # Enforce precedence with parentheses -(1 + 3) * 2 # => 8 +(1 + 3) * 2 # => 8 # Bitwise Operators -~2 # => -3 # bitwise not -3 & 5 # => 1 # bitwise and -2 | 4 # => 6 # bitwise or -2 $ 4 # => 6 # bitwise xor -2 >>> 1 # => 1 # logical shift right -2 >> 1 # => 1 # arithmetic shift right -2 << 1 # => 4 # logical/arithmetic shift left - -# You can use the bits function to see the binary representation of a number. -bits(12345) +~2 # => -3 # bitwise not +3 & 5 # => 1 # bitwise and +2 | 4 # => 6 # bitwise or +xor(2, 4) # => 6 # bitwise xor +2 >>> 1 # => 1 # logical shift right +2 >> 1 # => 1 # arithmetic shift right +2 << 1 # => 4 # logical/arithmetic shift left + +# Use the bitstring function to see the binary representation of a number. +bitstring(12345) # => "0000000000000000000000000000000000000000000000000011000000111001" -bits(12345.0) +bitstring(12345.0) # => "0100000011001000000111001000000000000000000000000000000000000000" # Boolean values are primitives @@ -65,40 +66,38 @@ true false # Boolean operators -!true # => false -!false # => true -1 == 1 # => true -2 == 1 # => false -1 != 1 # => false -2 != 1 # => true -1 < 10 # => true -1 > 10 # => false -2 <= 2 # => true -2 >= 2 # => true +!true # => false +!false # => true +1 == 1 # => true +2 == 1 # => false +1 != 1 # => false +2 != 1 # => true +1 < 10 # => true +1 > 10 # => false +2 <= 2 # => true +2 >= 2 # => true # Comparisons can be chained -1 < 2 < 3 # => true -2 < 3 < 2 # => false +1 < 2 < 3 # => true +2 < 3 < 2 # => false # Strings are created with " "This is a string." -# Julia has several types of strings, including ASCIIString and UTF8String. -# More on this in the Types section. - # Character literals are written with ' 'a' -# Some strings can be indexed like an array of characters -"This is a string"[1] # => 'T' # Julia indexes from 1 -# However, this is will not work well for UTF8 strings, -# so iterating over strings is recommended (map, for loops, etc). +# Strings are UTF8 encoded. Only if they contain only ASCII characters can +# they be safely indexed. +ascii("This is a string")[1] # => 'T' # Julia indexes from 1 +# Otherwise, iterating over strings is recommended (map, for loops, etc). # $ can be used for string interpolation: "2 + 2 = $(2 + 2)" # => "2 + 2 = 4" # You can put any Julia expression inside the parentheses. -# Another way to format strings is the printf macro. -@printf "%d is less than %f" 4.5 5.3 # 4.5 is less than 5.300000 +# Another way to format strings is the printf macro from the stdlib Printf. +using Printf +@printf "%d is less than %f\n" 4.5 5.3 # => 5 is less than 5.300000 # Printing is easy println("I'm Julia. Nice to meet you!") @@ -106,29 +105,29 @@ println("I'm Julia. Nice to meet you!") # String can be compared lexicographically "good" > "bye" # => true "good" == "good" # => true -"1 + 2 = 3" == "1 + 2 = $(1+2)" # => true +"1 + 2 = 3" == "1 + 2 = $(1 + 2)" # => true #################################################### ## 2. Variables and Collections #################################################### # You don't declare variables before assigning to them. -some_var = 5 # => 5 -some_var # => 5 +some_var = 5 # => 5 +some_var # => 5 # Accessing a previously unassigned variable is an error try - some_other_var # => ERROR: some_other_var not defined + some_other_var # => ERROR: UndefVarError: some_other_var not defined catch e println(e) end # Variable names start with a letter or underscore. # After that, you can use letters, digits, underscores, and exclamation points. -SomeOtherVar123! = 6 # => 6 +SomeOtherVar123! = 6 # => 6 # You can also use certain unicode characters -☃ = 8 # => 8 +☃ = 8 # => 8 # These are especially handy for mathematical notation 2 * π # => 6.283185307179586 @@ -147,165 +146,168 @@ SomeOtherVar123! = 6 # => 6 # functions are sometimes called mutating functions or in-place functions. # Arrays store a sequence of values indexed by integers 1 through n: -a = Int64[] # => 0-element Int64 Array +a = Int64[] # => 0-element Int64 Array # 1-dimensional array literals can be written with comma-separated values. -b = [4, 5, 6] # => 3-element Int64 Array: [4, 5, 6] -b = [4; 5; 6] # => 3-element Int64 Array: [4, 5, 6] -b[1] # => 4 -b[end] # => 6 +b = [4, 5, 6] # => 3-element Int64 Array: [4, 5, 6] +b = [4; 5; 6] # => 3-element Int64 Array: [4, 5, 6] +b[1] # => 4 +b[end] # => 6 # 2-dimensional arrays use space-separated values and semicolon-separated rows. -matrix = [1 2; 3 4] # => 2x2 Int64 Array: [1 2; 3 4] +matrix = [1 2; 3 4] # => 2x2 Int64 Array: [1 2; 3 4] -# Arrays of a particular Type -b = Int8[4, 5, 6] # => 3-element Int8 Array: [4, 5, 6] +# Arrays of a particular type +b = Int8[4, 5, 6] # => 3-element Int8 Array: [4, 5, 6] # Add stuff to the end of a list with push! and append! -push!(a,1) # => [1] -push!(a,2) # => [1,2] -push!(a,4) # => [1,2,4] -push!(a,3) # => [1,2,4,3] -append!(a,b) # => [1,2,4,3,4,5,6] +push!(a, 1) # => [1] +push!(a, 2) # => [1,2] +push!(a, 4) # => [1,2,4] +push!(a, 3) # => [1,2,4,3] +append!(a, b) # => [1,2,4,3,4,5,6] # Remove from the end with pop -pop!(b) # => 6 and b is now [4,5] +pop!(b) # => 6 and b is now [4,5] # Let's put it back -push!(b,6) # b is now [4,5,6] again. +push!(b, 6) # b is now [4,5,6] again. -a[1] # => 1 # remember that Julia indexes from 1, not 0! +a[1] # => 1 # remember that Julia indexes from 1, not 0! # end is a shorthand for the last index. It can be used in any # indexing expression -a[end] # => 6 +a[end] # => 6 -# we also have shift and unshift -shift!(a) # => 1 and a is now [2,4,3,4,5,6] -unshift!(a,7) # => [7,2,4,3,4,5,6] +# we also have popfirst! and pushfirst! +popfirst!(a) # => 1 and a is now [2,4,3,4,5,6] +pushfirst!(a, 7) # => [7,2,4,3,4,5,6] # Function names that end in exclamations points indicate that they modify # their argument. -arr = [5,4,6] # => 3-element Int64 Array: [5,4,6] -sort(arr) # => [4,5,6]; arr is still [5,4,6] -sort!(arr) # => [4,5,6]; arr is now [4,5,6] +arr = [5,4,6] # => 3-element Int64 Array: [5,4,6] +sort(arr) # => [4,5,6]; arr is still [5,4,6] +sort!(arr) # => [4,5,6]; arr is now [4,5,6] # Looking out of bounds is a BoundsError try - a[0] # => ERROR: BoundsError() in getindex at array.jl:270 - a[end+1] # => ERROR: BoundsError() in getindex at array.jl:270 + a[0] + # => BoundsError: attempt to access 7-element Array{Int64,1} at index [0] + a[end + 1] + # => BoundsError: attempt to access 7-element Array{Int64,1} at index [8] catch e println(e) end # Errors list the line and file they came from, even if it's in the standard -# library. If you built Julia from source, you can look in the folder base -# inside the julia folder to find these files. +# library. You can look in the folder share/julia inside the julia folder to +# find these files. # You can initialize arrays from ranges -a = [1:5;] # => 5-element Int64 Array: [1,2,3,4,5] +a = [1:5;] # => 5-element Int64 Array: [1,2,3,4,5] # You can look at ranges with slice syntax. -a[1:3] # => [1, 2, 3] -a[2:end] # => [2, 3, 4, 5] +a[1:3] # => [1, 2, 3] +a[2:end] # => [2, 3, 4, 5] # Remove elements from an array by index with splice! arr = [3,4,5] -splice!(arr,2) # => 4 ; arr is now [3,5] +splice!(arr, 2) # => 4 ; arr is now [3,5] # Concatenate lists with append! b = [1,2,3] -append!(a,b) # Now a is [1, 2, 3, 4, 5, 1, 2, 3] +append!(a, b) # Now a is [1, 2, 3, 4, 5, 1, 2, 3] # Check for existence in a list with in -in(1, a) # => true +in(1, a) # => true # Examine the length with length -length(a) # => 8 +length(a) # => 8 # Tuples are immutable. -tup = (1, 2, 3) # => (1,2,3) # an (Int64,Int64,Int64) tuple. -tup[1] # => 1 -try: - tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64) +tup = (1, 2, 3) # => (1,2,3) # an (Int64,Int64,Int64) tuple. +tup[1] # => 1 +try + tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64) catch e println(e) end -# Many list functions also work on tuples -length(tup) # => 3 -tup[1:2] # => (1,2) -in(2, tup) # => true +# Many array functions also work on tuples +length(tup) # => 3 +tup[1:2] # => (1,2) +in(2, tup) # => true # You can unpack tuples into variables -a, b, c = (1, 2, 3) # => (1,2,3) # a is now 1, b is now 2 and c is now 3 +a, b, c = (1, 2, 3) # => (1,2,3) # a is now 1, b is now 2 and c is now 3 # Tuples are created even if you leave out the parentheses -d, e, f = 4, 5, 6 # => (4,5,6) +d, e, f = 4, 5, 6 # => (4,5,6) # A 1-element tuple is distinct from the value it contains -(1,) == 1 # => false -(1) == 1 # => true +(1,) == 1 # => false +(1) == 1 # => true # Look how easy it is to swap two values -e, d = d, e # => (5,4) # d is now 5 and e is now 4 +e, d = d, e # => (5,4) # d is now 5 and e is now 4 # Dictionaries store mappings -empty_dict = Dict() # => Dict{Any,Any}() +empty_dict = Dict() # => Dict{Any,Any}() # You can create a dictionary using a literal -filled_dict = Dict("one"=> 1, "two"=> 2, "three"=> 3) -# => Dict{ASCIIString,Int64} +filled_dict = Dict("one" => 1, "two" => 2, "three" => 3) +# => Dict{String,Int64} # Look up values with [] -filled_dict["one"] # => 1 +filled_dict["one"] # => 1 # Get all keys keys(filled_dict) -# => KeyIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2]) +# => Base.KeySet for a Dict{String,Int64} with 3 entries. Keys: +# "two", "one", "three" # Note - dictionary keys are not sorted or in the order you inserted them. # Get all values values(filled_dict) -# => ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2]) +# => Base.ValueIterator{Dict{String,Int64}} with 3 entries. Values: 2, 1, 3 # Note - Same as above regarding key ordering. # Check for existence of keys in a dictionary with in, haskey -in(("one" => 1), filled_dict) # => true -in(("two" => 3), filled_dict) # => false -haskey(filled_dict, "one") # => true -haskey(filled_dict, 1) # => false +in(("one" => 1), filled_dict) # => true +in(("two" => 3), filled_dict) # => false +haskey(filled_dict, "one") # => true +haskey(filled_dict, 1) # => false # Trying to look up a non-existent key will raise an error try - filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489 + filled_dict["four"] # => KeyError: key "four" not found catch e println(e) end # Use the get method to avoid that error by providing a default value -# get(dictionary,key,default_value) -get(filled_dict,"one",4) # => 1 -get(filled_dict,"four",4) # => 4 +# get(dictionary, key, default_value) +get(filled_dict, "one", 4) # => 1 +get(filled_dict, "four", 4) # => 4 # Use Sets to represent collections of unordered, unique values -empty_set = Set() # => Set{Any}() +empty_set = Set() # => Set{Any}() # Initialize a set with values -filled_set = Set([1,2,2,3,4]) # => Set{Int64}(1,2,3,4) +filled_set = Set([1, 2, 2, 3, 4]) # => Set([4, 2, 3, 1]) # Add more values to a set -push!(filled_set,5) # => Set{Int64}(5,4,2,3,1) +push!(filled_set, 5) # => Set([4, 2, 3, 5, 1]) # Check if the values are in the set -in(2, filled_set) # => true -in(10, filled_set) # => false +in(2, filled_set) # => true +in(10, filled_set) # => false # There are functions for set intersection, union, and difference. -other_set = Set([3, 4, 5, 6]) # => Set{Int64}(6,4,5,3) -intersect(filled_set, other_set) # => Set{Int64}(3,4,5) -union(filled_set, other_set) # => Set{Int64}(1,2,3,4,5,6) -setdiff(Set([1,2,3,4]),Set([2,3,5])) # => Set{Int64}(1,4) +other_set = Set([3, 4, 5, 6]) # => Set([4, 3, 5, 6]) +intersect(filled_set, other_set) # => Set([4, 3, 5]) +union(filled_set, other_set) # => Set([4, 2, 3, 5, 6, 1]) +setdiff(Set([1,2,3,4]), Set([2,3,5])) # => Set([4, 1]) #################################################### @@ -328,7 +330,7 @@ end # For loops iterate over iterables. # Iterable types include Range, Array, Set, Dict, and AbstractString. -for animal=["dog", "cat", "mouse"] +for animal = ["dog", "cat", "mouse"] println("$animal is a mammal") # You can use $ to interpolate variables or expression into strings end @@ -346,15 +348,16 @@ end # cat is a mammal # mouse is a mammal -for a in Dict("dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal") - println("$(a[1]) is a $(a[2])") +for pair in Dict("dog" => "mammal", "cat" => "mammal", "mouse" => "mammal") + from, to = pair + println("$from is a $to") end # prints: # dog is a mammal # cat is a mammal # mouse is a mammal -for (k,v) in Dict("dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal") +for (k, v) in Dict("dog" => "mammal", "cat" => "mammal", "mouse" => "mammal") println("$k is a $v") end # prints: @@ -363,10 +366,11 @@ end # mouse is a mammal # While loops loop while a condition is true -x = 0 -while x < 4 - println(x) - x += 1 # Shorthand for x = x + 1 +let x = 0 + while x < 4 + println(x) + x += 1 # Shorthand for x = x + 1 + end end # prints: # 0 @@ -376,9 +380,9 @@ end # Handle exceptions with a try/catch block try - error("help") + error("help") catch e - println("caught it $e") + println("caught it $e") end # => caught it ErrorException("help") @@ -398,15 +402,15 @@ function add(x, y) x + y end -add(5, 6) # => 11 after printing out "x is 5 and y is 6" +add(5, 6) # => 11 after printing out "x is 5 and y is 6" # Compact assignment of functions -f_add(x, y) = x + y # => "f (generic function with 1 method)" -f_add(3, 4) # => 7 +f_add(x, y) = x + y # => "f (generic function with 1 method)" +f_add(3, 4) # => 7 # Function can also return multiple values as tuple -f(x, y) = x + y, x - y -f(3, 4) # => (7, -1) +fn(x, y) = x + y, x - y +fn(3, 4) # => (7, -1) # You can define functions that take a variable number of # positional arguments @@ -416,41 +420,41 @@ function varargs(args...) end # => varargs (generic function with 1 method) -varargs(1,2,3) # => (1,2,3) +varargs(1, 2, 3) # => (1,2,3) # The ... is called a splat. # We just used it in a function definition. # It can also be used in a function call, # where it will splat an Array or Tuple's contents into the argument list. -add([5,6]...) # this is equivalent to add(5,6) +add([5,6]...) # this is equivalent to add(5,6) -x = (5,6) # => (5,6) -add(x...) # this is equivalent to add(5,6) +x = (5, 6) # => (5,6) +add(x...) # this is equivalent to add(5,6) # You can define functions with optional positional arguments -function defaults(a,b,x=5,y=6) +function defaults(a, b, x=5, y=6) return "$a $b and $x $y" end -defaults('h','g') # => "h g and 5 6" -defaults('h','g','j') # => "h g and j 6" -defaults('h','g','j','k') # => "h g and j k" +defaults('h', 'g') # => "h g and 5 6" +defaults('h', 'g', 'j') # => "h g and j 6" +defaults('h', 'g', 'j', 'k') # => "h g and j k" try - defaults('h') # => ERROR: no method defaults(Char,) - defaults() # => ERROR: no methods defaults() + defaults('h') # => ERROR: no method defaults(Char,) + defaults() # => ERROR: no methods defaults() catch e println(e) end # You can define functions that take keyword arguments -function keyword_args(;k1=4,name2="hello") # note the ; - return Dict("k1"=>k1,"name2"=>name2) +function keyword_args(;k1=4, name2="hello") # note the ; + return Dict("k1" => k1, "name2" => name2) end -keyword_args(name2="ness") # => ["name2"=>"ness","k1"=>4] -keyword_args(k1="mine") # => ["k1"=>"mine","name2"=>"hello"] -keyword_args() # => ["name2"=>"hello","k1"=>4] +keyword_args(name2="ness") # => ["name2"=>"ness","k1"=>4] +keyword_args(k1="mine") # => ["k1"=>"mine","name2"=>"hello"] +keyword_args() # => ["name2"=>"hello","k1"=>4] # You can combine all kinds of arguments in the same function function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo") @@ -474,7 +478,7 @@ function create_adder(x) end # This is "stabby lambda syntax" for creating anonymous functions -(x -> x > 2)(3) # => true +(x -> x > 2)(3) # => true # This function is identical to create_adder implementation above. function create_adder(x) @@ -490,16 +494,17 @@ function create_adder(x) end add_10 = create_adder(10) -add_10(3) # => 13 +add_10(3) # => 13 # There are built-in higher order functions -map(add_10, [1,2,3]) # => [11, 12, 13] -filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7] +map(add_10, [1,2,3]) # => [11, 12, 13] +filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7] -# We can use list comprehensions for nicer maps -[add_10(i) for i=[1, 2, 3]] # => [11, 12, 13] +# We can use list comprehensions +[add_10(i) for i = [1, 2, 3]] # => [11, 12, 13] [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] #################################################### ## 5. Types @@ -508,11 +513,11 @@ filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7] # Julia has a type system. # Every value has a type; variables do not have types themselves. # You can use the `typeof` function to get the type of a value. -typeof(5) # => Int64 +typeof(5) # => Int64 # Types are first-class values -typeof(Int64) # => DataType -typeof(DataType) # => DataType +typeof(Int64) # => DataType +typeof(DataType) # => DataType # DataType is the type that represents types, including itself. # Types are used for documentation, optimizations, and dispatch. @@ -520,80 +525,77 @@ typeof(DataType) # => DataType # Users can define types # They are like records or structs in other languages. -# New types are defined using the `type` keyword. +# New types are defined using the `struct` keyword. -# type Name +# struct Name # field::OptionalType # ... # end -type Tiger - taillength::Float64 - coatcolor # not including a type annotation is the same as `::Any` +struct Tiger + taillength::Float64 + coatcolor # not including a type annotation is the same as `::Any` end # The default constructor's arguments are the properties # of the type, in the order they are listed in the definition -tigger = Tiger(3.5,"orange") # => Tiger(3.5,"orange") +tigger = Tiger(3.5, "orange") # => Tiger(3.5,"orange") # The type doubles as the constructor function for values of that type -sherekhan = typeof(tigger)(5.6,"fire") # => Tiger(5.6,"fire") +sherekhan = typeof(tigger)(5.6, "fire") # => Tiger(5.6,"fire") # These struct-style types are called concrete types # They can be instantiated, but cannot have subtypes. # The other kind of types is abstract types. # abstract Name -abstract Cat # just a name and point in the type hierarchy +abstract type Cat end # just a name and point in the type hierarchy # Abstract types cannot be instantiated, but can have subtypes. +using InteractiveUtils # defines the subtype and supertype function # For example, Number is an abstract type -subtypes(Number) # => 2-element Array{Any,1}: +subtypes(Number) # => 2-element Array{Any,1}: # Complex{T<:Real} # Real -subtypes(Cat) # => 0-element Array{Any,1} +subtypes(Cat) # => 0-element Array{Any,1} # AbstractString, as the name implies, is also an abstract type -subtypes(AbstractString) # 8-element Array{Any,1}: - # Base.SubstitutionString{T<:AbstractString} - # DirectIndexString - # RepString - # RevString{T<:AbstractString} - # RopeString - # SubString{T<:AbstractString} - # UTF16String - # UTF8String - -# Every type has a super type; use the `super` function to get it. -typeof(5) # => Int64 -super(Int64) # => Signed -super(Signed) # => Integer -super(Integer) # => Real -super(Real) # => Number -super(Number) # => Any -super(super(Signed)) # => Real -super(Any) # => Any +subtypes(AbstractString) # 4-element Array{Any,1}: + # String + # SubString + # SubstitutionString + # Test.GenericString + +# Every type has a super type; use the `supertype` function to get it. +typeof(5) # => Int64 +supertype(Int64) # => Signed +supertype(Signed) # => Integer +supertype(Integer) # => Real +supertype(Real) # => Number +supertype(Number) # => Any +supertype(supertype(Signed)) # => Real +supertype(Any) # => Any # All of these type, except for Int64, are abstract. -typeof("fire") # => ASCIIString -super(ASCIIString) # => DirectIndexString -super(DirectIndexString) # => AbstractString -# Likewise here with ASCIIString +typeof("fire") # => String +supertype(String) # => AbstractString +# Likewise here with String +supertype(SubString) # => AbstractString # <: is the subtyping operator -type Lion <: Cat # Lion is a subtype of Cat - mane_color - roar::AbstractString +struct Lion <: Cat # Lion is a subtype of Cat + mane_color + roar::AbstractString end # You can define more constructors for your type # Just define a function of the same name as the type # and call an existing constructor to get a value of the correct type -Lion(roar::AbstractString) = Lion("green",roar) +Lion(roar::AbstractString) = Lion("green", roar) # This is an outer constructor because it's outside the type definition -type Panther <: Cat # Panther is also a subtype of Cat - eye_color - Panther() = new("green") - # Panthers will only have this constructor, and no default constructor. +struct Panther <: Cat # Panther is also a subtype of Cat + eye_color + Panther() = new("green") + # Panthers will only have this constructor, and no default constructor. end # Using inner constructors, like Panther does, gives you control # over how values of the type can be created. @@ -611,35 +613,35 @@ end # Definitions for Lion, Panther, Tiger function meow(animal::Lion) - animal.roar # access type properties using dot notation + animal.roar # access type properties using dot notation end function meow(animal::Panther) - "grrr" + "grrr" end function meow(animal::Tiger) - "rawwwr" + "rawwwr" end # Testing the meow function -meow(tigger) # => "rawwr" -meow(Lion("brown","ROAAR")) # => "ROAAR" -meow(Panther()) # => "grrr" +meow(tigger) # => "rawwr" +meow(Lion("brown", "ROAAR")) # => "ROAAR" +meow(Panther()) # => "grrr" # Review the local type hierarchy -issubtype(Tiger,Cat) # => false -issubtype(Lion,Cat) # => true -issubtype(Panther,Cat) # => true +Tiger <: Cat # => false +Lion <: Cat # => true +Panther <: Cat # => true # Defining a function that takes Cats function pet_cat(cat::Cat) - println("The cat says $(meow(cat))") + println("The cat says $(meow(cat))") end -pet_cat(Lion("42")) # => prints "The cat says 42" +pet_cat(Lion("42")) # => prints "The cat says 42" try - pet_cat(tigger) # => ERROR: no method pet_cat(Tiger,) + pet_cat(tigger) # => ERROR: no method pet_cat(Tiger,) catch e println(e) end @@ -649,130 +651,132 @@ end # In Julia, all of the argument types contribute to selecting the best method. # Let's define a function with more arguments, so we can see the difference -function fight(t::Tiger,c::Cat) - println("The $(t.coatcolor) tiger wins!") +function fight(t::Tiger, c::Cat) + println("The $(t.coatcolor) tiger wins!") end # => fight (generic function with 1 method) -fight(tigger,Panther()) # => prints The orange tiger wins! -fight(tigger,Lion("ROAR")) # => prints The orange tiger wins! +fight(tigger, Panther()) # => prints The orange tiger wins! +fight(tigger, Lion("ROAR")) # => prints The orange tiger wins! # Let's change the behavior when the Cat is specifically a Lion -fight(t::Tiger,l::Lion) = println("The $(l.mane_color)-maned lion wins!") +fight(t::Tiger, l::Lion) = println("The $(l.mane_color)-maned lion wins!") # => fight (generic function with 2 methods) -fight(tigger,Panther()) # => prints The orange tiger wins! -fight(tigger,Lion("ROAR")) # => prints The green-maned lion wins! +fight(tigger, Panther()) # => prints The orange tiger wins! +fight(tigger, Lion("ROAR")) # => prints The green-maned lion wins! # We don't need a Tiger in order to fight -fight(l::Lion,c::Cat) = println("The victorious cat says $(meow(c))") +fight(l::Lion, c::Cat) = println("The victorious cat says $(meow(c))") # => fight (generic function with 3 methods) -fight(Lion("balooga!"),Panther()) # => prints The victorious cat says grrr +fight(Lion("balooga!"), Panther()) # => prints The victorious cat says grrr try - fight(Panther(),Lion("RAWR")) # => ERROR: no method fight(Panther,Lion) -catch + fight(Panther(), Lion("RAWR")) +catch e + println(e) + # => MethodError(fight, (Panther("green"), Lion("green", "RAWR")), + # 0x000000000000557b) end # Also let the cat go first -fight(c::Cat,l::Lion) = println("The cat beats the Lion") -# => Warning: New definition -# fight(Cat,Lion) at none:1 -# is ambiguous with -# fight(Lion,Cat) at none:2. -# Make sure -# fight(Lion,Lion) -# is defined first. -#fight (generic function with 4 methods) +fight(c::Cat, l::Lion) = println("The cat beats the Lion") # This warning is because it's unclear which fight will be called in: -fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The victorious cat says rarrr +try + fight(Lion("RAR"), Lion("brown", "rarrr")) + # => prints The victorious cat says rarrr +catch e + println(e) + # => MethodError(fight, (Lion("green", "RAR"), Lion("brown", "rarrr")), + # 0x000000000000557c) +end # The result may be different in other versions of Julia -fight(l::Lion,l2::Lion) = println("The lions come to a tie") -fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The lions come to a tie +fight(l::Lion, l2::Lion) = println("The lions come to a tie") +fight(Lion("RAR"), Lion("brown", "rarrr")) # => prints The lions come to a tie # Under the hood # You can take a look at the llvm and the assembly code generated. -square_area(l) = l * l # square_area (generic function with 1 method) +square_area(l) = l * l # square_area (generic function with 1 method) -square_area(5) #25 +square_area(5) # => 25 # What happens when we feed square_area an integer? code_native(square_area, (Int32,)) - # .section __TEXT,__text,regular,pure_instructions - # Filename: none - # Source line: 1 # Prologue - # push RBP - # mov RBP, RSP - # Source line: 1 - # movsxd RAX, EDI # Fetch l from memory? - # imul RAX, RAX # Square l and store the result in RAX - # pop RBP # Restore old base pointer - # ret # Result will still be in RAX + # .section __TEXT,__text,regular,pure_instructions + # Filename: none + # Source line: 1 # Prologue + # push RBP + # mov RBP, RSP + # Source line: 1 + # movsxd RAX, EDI # Fetch l from memory? + # imul RAX, RAX # Square l and store the result in RAX + # pop RBP # Restore old base pointer + # ret # Result will still be in RAX code_native(square_area, (Float32,)) - # .section __TEXT,__text,regular,pure_instructions - # Filename: none - # Source line: 1 - # push RBP - # mov RBP, RSP - # Source line: 1 - # vmulss XMM0, XMM0, XMM0 # Scalar single precision multiply (AVX) - # pop RBP - # ret + # .section __TEXT,__text,regular,pure_instructions + # Filename: none + # Source line: 1 + # push RBP + # mov RBP, RSP + # Source line: 1 + # vmulss XMM0, XMM0, XMM0 # Scalar single precision multiply (AVX) + # pop RBP + # ret code_native(square_area, (Float64,)) - # .section __TEXT,__text,regular,pure_instructions - # Filename: none - # Source line: 1 - # push RBP - # mov RBP, RSP - # Source line: 1 - # vmulsd XMM0, XMM0, XMM0 # Scalar double precision multiply (AVX) - # pop RBP - # ret - # + # .section __TEXT,__text,regular,pure_instructions + # Filename: none + # Source line: 1 + # push RBP + # mov RBP, RSP + # Source line: 1 + # vmulsd XMM0, XMM0, XMM0 # Scalar double precision multiply (AVX) + # pop RBP + # ret + # # Note that julia will use floating point instructions if any of the # arguments are floats. # Let's calculate the area of a circle circle_area(r) = pi * r * r # circle_area (generic function with 1 method) -circle_area(5) # 78.53981633974483 +circle_area(5) # 78.53981633974483 code_native(circle_area, (Int32,)) - # .section __TEXT,__text,regular,pure_instructions - # Filename: none - # Source line: 1 - # push RBP - # mov RBP, RSP - # Source line: 1 - # vcvtsi2sd XMM0, XMM0, EDI # Load integer (r) from memory - # movabs RAX, 4593140240 # Load pi - # vmulsd XMM1, XMM0, QWORD PTR [RAX] # pi * r - # vmulsd XMM0, XMM0, XMM1 # (pi * r) * r - # pop RBP - # ret - # + # .section __TEXT,__text,regular,pure_instructions + # Filename: none + # Source line: 1 + # push RBP + # mov RBP, RSP + # Source line: 1 + # vcvtsi2sd XMM0, XMM0, EDI # Load integer (r) from memory + # movabs RAX, 4593140240 # Load pi + # vmulsd XMM1, XMM0, QWORD PTR [RAX] # pi * r + # vmulsd XMM0, XMM0, XMM1 # (pi * r) * r + # pop RBP + # ret + # code_native(circle_area, (Float64,)) - # .section __TEXT,__text,regular,pure_instructions - # Filename: none - # Source line: 1 - # push RBP - # mov RBP, RSP - # movabs RAX, 4593140496 - # Source line: 1 - # vmulsd XMM1, XMM0, QWORD PTR [RAX] - # vmulsd XMM0, XMM1, XMM0 - # pop RBP - # ret - # + # .section __TEXT,__text,regular,pure_instructions + # Filename: none + # Source line: 1 + # push RBP + # mov RBP, RSP + # movabs RAX, 4593140496 + # Source line: 1 + # vmulsd XMM1, XMM0, QWORD PTR [RAX] + # vmulsd XMM0, XMM1, XMM0 + # pop RBP + # ret + # ``` ## Further Reading -You can get a lot more detail from [The Julia Manual](http://docs.julialang.org/en/latest/#Manual-1) +You can get a lot more detail from the [Julia Documentation](https://docs.julialang.org/) The best place to get help with Julia is the (very friendly) [Discourse forum](https://discourse.julialang.org/). diff --git a/ko-kr/markdown-kr.html.markdown b/ko-kr/markdown-kr.html.markdown index bfa2a877..4e115ec5 100644 --- a/ko-kr/markdown-kr.html.markdown +++ b/ko-kr/markdown-kr.html.markdown @@ -25,7 +25,7 @@ lang: ko-kr ## HTML 요소 HTML은 마크다운의 수퍼셋입니다. 모든 HTML 파일은 유효한 마크다운이라는 것입니다. -```markdown +```md <!--따라서 주석과 같은 HTML 요소들을 마크다운에 사용할 수 있으며, 마크다운 파서에 영향을 받지 않을 것입니다. 하지만 마크다운 파일에서 HTML 요소를 만든다면 그 요소의 안에서는 마크다운 문법을 사용할 수 없습니다.--> diff --git a/lambda-calculus.html.markdown b/lambda-calculus.html.markdown index 6103c015..72ed78ba 100644 --- a/lambda-calculus.html.markdown +++ b/lambda-calculus.html.markdown @@ -3,6 +3,7 @@ category: Algorithms & Data Structures name: Lambda Calculus contributors: - ["Max Sun", "http://github.com/maxsun"] + - ["Yan Hui Hang", "http://github.com/yanhh0"] --- # Lambda Calculus @@ -114,8 +115,100 @@ Using successor, we can define add: **Challenge:** try defining your own multiplication function! +## Get even smaller: SKI, SK and Iota + +### SKI Combinator Calculus + +Let S, K, I be the following functions: + +`I x = x` + +`K x y = x` + +`S x y z = x z (y z)` + +We can convert an expression in the lambda calculus to an expression +in the SKI combinator calculus: + +1. `λx.x = I` +2. `λx.c = Kc` +3. `λx.(y z) = S (λx.y) (λx.z)` + +Take the church number 2 for example: + +`2 = λf.λx.f(f x)` + +For the inner part `λx.f(f x)`: +``` + λx.f(f x) += S (λx.f) (λx.(f x)) (case 3) += S (K f) (S (λx.f) (λx.x)) (case 2, 3) += S (K f) (S (K f) I) (case 2, 1) +``` + +So: +``` + 2 += λf.λx.f(f x) += λf.(S (K f) (S (K f) I)) += λf.((S (K f)) (S (K f) I)) += S (λf.(S (K f))) (λf.(S (K f) I)) (case 3) +``` + +For the first argument `λf.(S (K f))`: +``` + λf.(S (K f)) += S (λf.S) (λf.(K f)) (case 3) += S (K S) (S (λf.K) (λf.f)) (case 2, 3) += S (K S) (S (K K) I) (case 2, 3) +``` + +For the second argument `λf.(S (K f) I)`: +``` + λf.(S (K f) I) += λf.((S (K f)) I) += S (λf.(S (K f))) (λf.I) (case 3) += S (S (λf.S) (λf.(K f))) (K I) (case 2, 3) += S (S (K S) (S (λf.K) (λf.f))) (K I) (case 1, 3) += S (S (K S) (S (K K) I)) (K I) (case 1, 2) +``` + +Merging them up: +``` + 2 += S (λf.(S (K f))) (λf.(S (K f) I)) += S (S (K S) (S (K K) I)) (S (S (K S) (S (K K) I)) (K I)) +``` + +Expanding this, we would end up with the same expression for the +church number 2 again. + +### SK Combinator Calculus + +The SKI combinator calculus can still be reduced further. We can +remove the I combinator by noting that `I = SKK`. We can substitute +all `I`'s with `SKK`. + +### Iota Combinator + +The SK combinator calculus is still not minimal. Defining: + +``` +ι = λf.((f S) K) +``` + +We have: + +``` +I = ιι +K = ι(ιI) = ι(ι(ιι)) +S = ι(K) = ι(ι(ι(ιι))) +``` + ## 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 +3. [Wikipedia - Lambda Calculus](https://en.wikipedia.org/wiki/Lambda_calculus) +4. [Wikipedia - SKI combinator calculus](https://en.wikipedia.org/wiki/SKI_combinator_calculus) +5. [Wikipedia - Iota and Jot](https://en.wikipedia.org/wiki/Iota_and_Jot) diff --git a/markdown.html.markdown b/markdown.html.markdown index ece2567c..cf4286e2 100644 --- a/markdown.html.markdown +++ b/markdown.html.markdown @@ -197,7 +197,7 @@ inside your code end ``` -Inline code can be created using the backtick character ` +Inline code can be created using the backtick character `` ` `` ```md John didn't even know what the `go_to()` function did! diff --git a/mips.html.markdown b/mips.html.markdown new file mode 100644 index 00000000..1133f769 --- /dev/null +++ b/mips.html.markdown @@ -0,0 +1,366 @@ +--- +language: "MIPS Assembly" +filename: MIPS.asm +contributors: + - ["Stanley Lim", "https://github.com/Spiderpig86"] +--- + +The MIPS (Microprocessor without Interlocked Pipeline Stages) Assembly language +is designed to work with the MIPS microprocessor paradigm designed by J. L. +Hennessy in 1981. These RISC processors are used in embedded systems such as +gateways and routers. + +[Read More](https://en.wikipedia.org/wiki/MIPS_architecture) + +```assembly +# Comments are denoted with a '#' + +# Everything that occurs after a '#' will be ignored by the assembler's lexer. + +# Programs typically contain a .data and .text sections + +.data # Section where data is stored in memory (allocated in RAM), similar to + # variables in higher level languages + + # Declarations follow a ( label: .type value(s) ) form of declaration + hello_world: .asciiz "Hello World\n" # Declare a null terminated string + num1: .word 42 # Integers are referred to as words + # (32 bit value) + + arr1: .word 1, 2, 3, 4, 5 # Array of words + arr2: .byte 'a', 'b' # Array of chars (1 byte each) + buffer: .space 60 # Allocates space in the RAM + # (not cleared to 0) + + # Datatype sizes + _byte: .byte 'a' # 1 byte + _halfword: .half 53 # 2 bytes + _word: .word 3 # 4 bytes + _float: .float 3.14 # 4 bytes + _double: .double 7.0 # 8 bytes + + .align 2 # Memory alignment of data, where + # number indicates byte alignment in + # powers of 2. (.align 2 represents + # word alignment since 2^2 = 4 bytes) + +.text # Section that contains instructions + # and program logic +.globl _main # Declares an instruction label as + # global, making it accessible to + # other files + + _main: # MIPS programs execute instructions + # sequentially, where the code under + # this label will be executed firsts + + # Let's print "hello world" + la $a0, hello_world # Load address of string stored in + # memory + li $v0, 4 # Load the syscall value (indicating + # type of functionality) + syscall # Perform the specified syscall with + # the given argument ($a0) + + # Registers (used to hold data during program execution) + # $t0 - $t9 # Temporary registers used for + # intermediate calculations inside + # subroutines (not saved across + # function calls) + + # $s0 - $s7 # Saved registers where values are + # saved across subroutine calls. + # Typically saved in stack + + # $a0 - $a3 # Argument registers for passing in + # arguments for subroutines + # $v0 - $v1 # Return registers for returning + # values to caller function + + # Types of load/store instructions + la $t0, label # Copy the address of a value in + # memory specified by the label into + # register $t0 + lw $t0, label # Copy a word value from memory + lw $t1, 4($s0) # Copy a word value from an address + # stored in a register with an offset + # of 4 bytes (addr + 4) + lb $t2, label # Copy a byte value to the lower order + # portion of the register $t2 + lb $t2, 0($s0) # Copy a byte value from the source + # address in $s0 with offset 0 + # Same idea with 'lh' for halfwords + + sw $t0, label # Store word value into memory address + # mapped by label + sw $t0, 8($s0) # Store word value into address + # specified in $s0 and offset of 8 bytes + # Same idea using 'sb' and 'sh' for bytes and halfwords. 'sa' does not exist + +### Math ### + _math: + # Remember to load your values into a register + lw $t0, num # From the data section + li $t0, 5 # Or from an immediate (constant) + li $t1, 6 + add $t2, $t0, $t1 # $t2 = $t0 + $t1 + sub $t2, $t0, $t1 # $t2 = $t0 - $t1 + mul $t2, $t0, $t1 # $t2 = $t0 * $t1 + div $t2, $t0, $t1 # $t2 = $t0 / $t1 (Might not be + # supported in some versons of MARS) + div $t0, $t1 # Performs $t0 / $t1. Get the quotient + # using 'mflo' and remainder using 'mfhi' + + # Bitwise Shifting + sll $t0, $t0, 2 # Bitwise shift to the left with + # immediate (constant value) of 2 + sllv $t0, $t1, $t2 # Shift left by a variable amount in + # register + srl $t0, $t0, 5 # Bitwise shift to the right (does + # not sign preserve, sign-extends with 0) + srlv $t0, $t1, $t2 # Shift right by a variable amount in + # a register + sra $t0, $t0, 7 # Bitwise arithmetic shift to the right + # (preserves sign) + srav $t0, $t1, $t2 # Shift right by a variable amount + # in a register + + # Bitwise operators + and $t0, $t1, $t2 # Bitwise AND + andi $t0, $t1, 0xFFF # Bitwise AND with immediate + or $t0, $t1, $t2 # Bitwise OR + ori $t0, $t1, 0xFFF # Bitwise OR with immediate + xor $t0, $t1, $t2 # Bitwise XOR + xori $t0, $t1, 0xFFF # Bitwise XOR with immediate + nor $t0, $t1, $t2 # Bitwise NOR + +## BRANCHING ## + _branching: + # The basic format of these branching instructions typically follow <instr> + # <reg1> <reg2> <label> where label is the label we want to jump to if the + # given conditional evaluates to true + # Sometimes it is easier to write the conditional logic backwards, as seen + # in the simple if statement example below + + beq $t0, $t1, reg_eq # Will branch to reg_eq if + # $t0 == $t1, otherwise + # execute the next line + bne $t0, $t1, reg_neq # Branches when $t0 != $t1 + b branch_target # Unconditional branch, will always execute + beqz $t0, req_eq_zero # Branches when $t0 == 0 + bnez $t0, req_neq_zero # Branches when $t0 != 0 + bgt $t0, $t1, t0_gt_t1 # Branches when $t0 > $t1 + bge $t0, $t1, t0_gte_t1 # Branches when $t0 >= $t1 + bgtz $t0, t0_gt0 # Branches when $t0 > 0 + blt $t0, $t1, t0_gt_t1 # Branches when $t0 < $t1 + ble $t0, $t1, t0_gte_t1 # Branches when $t0 <= $t1 + bltz $t0, t0_lt0 # Branches when $t0 < 0 + slt $s0, $t0, $t1 # Instruction that sends a signal when + # $t0 < $t1 with reuslt in $s0 (1 for true) + + # Simple if statement + # if (i == j) + # f = g + h; + # f = f - i; + + # Let $s0 = f, $s1 = g, $s2 = h, $s3 = i, $s4 = j + bne $s3, $s4, L1 # if (i !=j) + add $s0, $s1, $s2 # f = g + h + + L1: + sub $s0, $s0, $s3 # f = f - i + + # Below is an example of finding the max of 3 numbers + # A direct translation in Java from MIPS logic: + # if (a > b) + # if (a > c) + # max = a; + # else + # max = c; + # else + # max = b; + # else + # max = c; + + # Let $s0 = a, $s1 = b, $s2 = c, $v0 = return register + ble $s0, $s1, a_LTE_b # if (a <= b) branch(a_LTE_b) + ble $s0, $s2, max_C # if (a > b && a <=c) branch(max_C) + move $v0, $s1 # else [a > b && a > c] max = a + j done # Jump to the end of the program + + a_LTE_b: # Label for when a <= b + ble $s1, $s2, max_C # if (a <= b && b <= c) branch(max_C) + move $v0, $s1 # if (a <= b && b > c) max = b + j done # Jump to done + + max_C: + move $v0, $s2 # max = c + + done: # End of program + +## LOOPS ## + _loops: + # The basic structure of loops is having an exit condition and a jump + instruction to continue its execution + li $t0, 0 + while: + bgt $t0, 10, end_while # While $t0 is less than 10, keep iterating + addi $t0, $t0, 1 # Increment the value + j while # Jump back to the beginning of the loop + end_while: + + # 2D Matrix Traversal + # Assume that $a0 stores the address of an integer matrix which is 3 x 3 + li $t0, 0 # Counter for i + li $t1, 0 # Counter for j + matrix_row: + bgt $t0, 3, matrix_row_end + + matrix_col: + bgt $t1, 3, matrix_col_end + + # Do stuff + + addi $t1, $t1, 1 # Increment the col counter + matrix_col_end: + + # Do stuff + + addi $t0, $t0, 1 + matrix_row_end: + +## FUNCTIONS ## + _functions: + # Functions are callable procedures that can accept arguments and return + values all denoted with labels, like above + + main: # Programs begin with main func + jal return_1 # jal will store the current PC in $ra + # and then jump to return_1 + + # What if we want to pass in args? + # First we must pass in our parameters to the argument registers + li $a0, 1 + li $a1, 2 + jal sum # Now we can call the function + + # How about recursion? + # This is a bit more work since we need to make sure we save and restore + # the previous PC in $ra since jal will automatically overwrite on each call + li $a0, 3 + jal fact + + li $v0, 10 + syscall + + # This function returns 1 + return_1: + li $v0, 1 # Load val in return register $v0 + jr $ra # Jump back to old PC to continue exec + + + # Function with 2 args + sum: + add $v0, $a0, $a1 + jr $ra # Return + + # Recursive function to find factorial + fact: + addi $sp, $sp, -8 # Allocate space in stack + sw $s0, ($sp) # Store reg that holds current num + sw $ra, 4($sp) # Store previous PC + + li $v0, 1 # Init return value + beq $a0, 0, fact_done # Finish if param is 0 + + # Otherwise, continue recursion + move $s0, $a0 # Copy $a0 to $s0 + sub $a0, $a0, 1 + jal fact + + mul $v0, $s0, $v0 # Multiplication is done + + fact_done: + lw $s0, ($sp) + lw $ra, ($sp) # Restore the PC + addi $sp, $sp, 8 + + jr $ra + +## MACROS ## + _macros: + # Macros are extremly useful for substituting repeated code blocks with a + # single label for better readability + # These are in no means substitutes for functions + # These must be declared before it is used + + # Macro for printing new lines (since these can be very repetitive) + .macro println() + la $a0, newline # New line string stored here + li $v0, 4 + syscall + .end_macro + + println() # Assembler will copy that block of + # code here before running + + # Parameters can be passed in through macros. + # These are denoted by a '%' sign with any name you choose + .macro print_int(%num) + li $v0, 1 + lw $a0, %num + syscall + .end_macro + + li $t0, 1 + print_int($t0) + + # We can also pass in immediates for macros + .macro immediates(%a, %b) + add $t0, %a, %b + .end_macro + + immediates(3, 5) + + # Along with passing in labels + .macro print(%string) + la $a0, %string + li $v0, 4 + syscall + .end_macro + + print(hello_world) + +## ARRAYS ## +.data + list: .word 3, 0, 1, 2, 6 # This is an array of words + char_arr: .asciiz "hello" # This is a char array + buffer: .space 128 # Allocates a block in memory, does + # not automatically clear + # These blocks of memory are aligned + # next each other + +.text + la $s0, list # Load address of list + li $t0, 0 # Counter + li $t1, 5 # Length of the list + + loop: + bgt $t0, $t1, end_loop + + lw $a0, ($s0) + li $v0, 1 + syscall # Print the number + + addi $s0, $s0, 4 # Size of a word is 4 bytes + addi $t0, $t0, 1 # Increment + j loop + end_loop: + +## INCLUDE ## +# You do this to import external files into your program (behind the scenes, +# it really just takes whatever code that is in that file and places it where +# the include statement is) +.include "somefile.asm" + +``` diff --git a/nl-nl/markdown-nl.html.markdown b/nl-nl/markdown-nl.html.markdown index 35cc67c5..b5b4681c 100644 --- a/nl-nl/markdown-nl.html.markdown +++ b/nl-nl/markdown-nl.html.markdown @@ -12,7 +12,7 @@ Markdown is gecreëerd door John Gruber in 2004. Het is bedoeld om met een gemak schrijven syntax te zijn die gemakkelijk omgevormd kan worden naar HTML (en op heden verschillende andere formaten) -```markdown +```md <!-- Markdown erft over van HTML, dus ieder HTML bestand is een geldig Markdown bestand. Dit betekend ook dat html elementen gebruikt kunnen worden in Markdown zoals het commentaar element. Echter, als je een html element maakt in een Markdown diff --git a/pt-br/awk-pt.html.markdown b/pt-br/awk-pt.html.markdown index 75b73abe..761f5294 100644 --- a/pt-br/awk-pt.html.markdown +++ b/pt-br/awk-pt.html.markdown @@ -171,7 +171,7 @@ function arithmetic_functions(a, b, c, d) { # Muitas implementações AWK possuem algumas funções trigonométricas padrão localvar = sin(a) localvar = cos(a) - localvar = atan2(a, b) # arco-tangente de b / a + localvar = atan2(b, a) # arco-tangente de b / a # E conteúdo logarítmico localvar = exp(a) diff --git a/pt-br/common-lisp-pt.html.markdown b/pt-br/common-lisp-pt.html.markdown index c3381824..c22cfd8e 100644 --- a/pt-br/common-lisp-pt.html.markdown +++ b/pt-br/common-lisp-pt.html.markdown @@ -19,7 +19,7 @@ Outro livro recente e popular é o [Land of Lisp](http://landoflisp.com/). -```common-lisp +```lisp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 0. Sintaxe diff --git a/pt-br/markdown-pt.html.markdown b/pt-br/markdown-pt.html.markdown index f22093f9..c2aa515d 100644 --- a/pt-br/markdown-pt.html.markdown +++ b/pt-br/markdown-pt.html.markdown @@ -14,7 +14,7 @@ escrever sintaxe que converte facilmente em HTML (hoje, suporta outros formatos Dê-me feedback tanto quanto você quiser! / Sinta-se livre para a garfar (fork) e puxar o projeto (pull request) -```markdown +```md <!-- Markdown é um superconjunto do HTML, de modo que qualquer arvquivo HTML é um arquivo Markdown válido, isso significa que nós podemos usar elementos HTML em Markdown, como o elemento de comentário, e eles não serão afetados pelo analisador diff --git a/pt-br/visualbasic-pt.html.markdown b/pt-br/visualbasic-pt.html.markdown index b94ab609..2a7205cd 100644 --- a/pt-br/visualbasic-pt.html.markdown +++ b/pt-br/visualbasic-pt.html.markdown @@ -8,7 +8,7 @@ lang: pt-br filename: learnvisualbasic-pt.vb --- -```vb +``` Module Module1 module Module1 diff --git a/python3.html.markdown b/python3.html.markdown index 019934cb..b378a8c6 100644 --- a/python3.html.markdown +++ b/python3.html.markdown @@ -7,6 +7,7 @@ contributors: - ["Zachary Ferguson", "http://github.com/zfergus2"] - ["evuez", "http://github.com/evuez"] - ["Rommel Martinez", "https://ebzzry.io"] + - ["Roberto Fernandez Diaz", "https://github.com/robertofd1995"] filename: learnpython3.py --- @@ -138,6 +139,10 @@ len("This is a string") # => 16 # still use the old style of formatting: "%s can be %s the %s way" % ("Strings", "interpolated", "old") # => "Strings can be interpolated the old way" +# You can also format using f-strings or formatted string literals +name = "Reiko" +f"She said her name is {name}." # => "She said her name is Reiko" + # None is an object None # => None @@ -348,6 +353,8 @@ valid_set = {(1,), 1} # Add one more item to the set filled_set = some_set filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5} +# Sets do not have duplicate elements +filled_set.add(5) # it remains as before {1, 2, 3, 4, 5} # Do set intersection with & other_set = {3, 4, 5, 6} diff --git a/ro-ro/elixir-ro.html.markdown b/ro-ro/elixir-ro.html.markdown new file mode 100644 index 00000000..d8b261af --- /dev/null +++ b/ro-ro/elixir-ro.html.markdown @@ -0,0 +1,459 @@ +--- +language: elixir +contributors: + - ["Joao Marques", "http://github.com/mrshankly"] + - ["Dzianis Dashkevich", "https://github.com/dskecse"] + - ["Ryan Plant", "https://github.com/ryanplant-au"] + - ["Ev Bogdanov", "https://github.com/evbogdanov"] +translators: + - ["Vitalie Lazu", "https://github.com/vitaliel"] + +filename: learnelixir-ro.ex +--- + +Elixir este un limbaj funcțional modern construit pe baza mașinii virtuale Erlang. +E total compatibil cu Erlang, dar are o sintaxă mai prietenoasă și propune mai multe +posibilități. + +```elixir + +# Comentariile de o linie încep cu simbolul diez. + +# Pentru comentarii pe mai multe linii nu există sintaxă separată, +# de aceea folosiți mai multe linii cu comentarii. + +# Pentru a folosi shell-ul elixir utilizați comanda `iex`. +# Compilați modulele cu comanda `elixirc`. + +# Ambele comenzi vor lucra în terminal, dacă ați instalat Elixir corect. + +## --------------------------- +## -- Tipuri de bază +## --------------------------- + +# Numere +3 # număr întreg +0x1F # număr întreg +3.0 # număr cu virgulă mobilă + +# Atomii, sunt constante nenumerice. Ei încep cu `:`. +:salut # atom + +# Tuplele sunt păstrate în memorie consecutiv. +{1,2,3} # tuple + +# Putem accesa elementul tuplelui folosind funcția `elem`: +elem({1, 2, 3}, 0) #=> 1 + +# Listele sunt implementate ca liste înlănțuite. +[1,2,3] # listă + +# Fiecare listă ne vidă are cap (primul element al listei) +# și coadă (restul elementelor). +# Putem accesa capul și coada listei cum urmează: +[cap | coadă] = [1,2,3] +cap #=> 1 +coadă #=> [2, 3] + +# În Elixir, ca și în Erlang, simbolul `=` denotă potrivirea șabloanelor și +# nu atribuire. +# +# Aceasta înseamnă că expresia din stînga (șablonul) se potrivește cu +# expresia din dreaptă. +# +# În modul acesta exemplul de mai sus lucrează accesînd capul și coada unei liste. + +# Potrivirea șablonului va da eroare cînd expresiile din stînga și dreapta nu se +# potrivesc, în exemplu acesta tuplele au lungime diferită. +{a, b, c} = {1, 2} #=> ** (MatchError) + +# Există și date binare +<<1,2,3>> + +# Sunt două tipuri de șiruri de caractere +"salut" # șir de caractere Elixir +'salut' # listă de caractere Erlang + +# Șir de caractere pe mai multe linii +""" +Sunt un șir de caractere +pe mai multe linii. +""" +#=> "Sunt un șir de caractere\npe mai multe linii..\n" + +# Șirurile de caractere sunt codificate în UTF-8: +"Bună dimineața" #=> "Bună dimineața" + +# Șirurile de caractere sunt date binare, listele de caractere doar liste. +<<?a, ?b, ?c>> #=> "abc" +[?a, ?b, ?c] #=> 'abc' + +# `?a` în Elixir întoarce codul ASCII pentru litera `a` +?a #=> 97 + +# Pentru a concatena listele folosiți `++`, pentru date binare - `<>` +[1,2,3] ++ [4,5] #=> [1,2,3,4,5] +'Salut ' ++ 'lume' #=> 'Salut lume' + +<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>> +"Salut " <> "lume" #=> "Salut lume" + +# Diapazoanele sunt reprezentate ca `început..sfîrșit` (inclusiv) +1..10 #=> 1..10 +început..sfîrșit = 1..10 # Putem folosi potrivirea șabloanelor cu diapazoane de asemenea +[început, sfîrșit] #=> [1, 10] + +# Dicţionarele stochează chei şi o valoare pentru fiecare cheie +genuri = %{"Ion" => "bărbat", "Maria" => "femeie"} +genuri["Ion"] #=> "bărbat" + +# Dicționare cu chei de tip atom au sintaxă specială +genuri = %{ion: "bărbat", maria: "femeie"} +genuri.ion #=> "bărbat" + +## --------------------------- +## -- Operatori +## --------------------------- + +# Operații matematice +1 + 1 #=> 2 +10 - 5 #=> 5 +5 * 2 #=> 10 +10 / 2 #=> 5.0 + +# În Elixir operatorul `/` întotdeauna întoarce un număr cu virgulă mobilă. + +# Folosiți `div` pentru împărțirea numerelor întregi +div(10, 2) #=> 5 + +# Pentru a obține restul de la împărțire utilizați `rem` +rem(10, 3) #=> 1 + +# Există și operatori booleni: `or`, `and` and `not`. +# Acești operatori așteaptă ca primul argument o expresie booleană. +true and true #=> true +false or true #=> true +1 and true #=> ** (BadBooleanError) + +# Elixir de asemenea oferă `||`, `&&` și `!` care acceptă argumente de orice tip. +# Toate valorile în afară de `false` și `nil` se vor evalua ca `true`. +1 || true #=> 1 +false && 1 #=> false +nil && 20 #=> nil +!true #=> false + +# Operatori de comparație: `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` și `>` +1 == 1 #=> true +1 != 1 #=> false +1 < 2 #=> true + +# `===` și `!==` au strictețe mai mare cînd comparăm numere întregi și reale: +1 == 1.0 #=> true +1 === 1.0 #=> false + +# Putem compara de asemenea și date de diferite tipuri: +1 < :salut #=> true + +# La compararea diferitor tipuri folosiți următoare prioritate: +# număr < atom < referință < funcție < port < proces < tuple < listă < șir de caractere + +# Cităm pe Joe Armstrong în acest caz: "Ordinea actuală nu e importantă, +dar că ordinea totală este bine definită este important." + +## --------------------------- +## -- Ordinea execuției +## --------------------------- + +# expresia `if` +if false do + "Aceasta nu veți vedea niciodată" +else + "Aceasta veți vedea" +end + +# expresia opusă `unless` +unless true do + "Aceasta nu veți vedea niciodată" +else + "Aceasta veți vedea" +end + +# Țineți minte potrivirea șabloanelor? Multe structuri în Elixir se bazează pe ea. + +# `case` ne permite să comparăm o valoare cu multe șabloane: +case {:unu, :doi} do + {:patru, :cinci} -> + "Aceasta nu se potrivește" + {:unu, x} -> + "Aceasta se potrivește și atribuie lui `x` `:doi` în acest bloc" + _ -> + "Aceasta se va potrivi cu orice valoare" +end + +# Simbolul `_` se numește variabila anonimă. +# Folosiți-l pentru valori ce nu vă interesează. +# De exemplu, dacă doar capul listei ne intereseaza: +[cap | _] = [1,2,3] +cap #=> 1 + +# Pentru o citire mai bună putem scri: +[cap | _coadă] = [:a, :b, :c] +cap #=> :a + +# `cond` ne permite să verificăm multe condiții de odată. +# Folosiți `cond` în schimbul la multe expresii `if`. +cond do + 1 + 1 == 3 -> + "Aceasta nu veți vedea niciodată" + 2 * 5 == 12 -> + "Pe mine la fel" + 1 + 2 == 3 -> + "Aceasta veți vedea" +end + +# Este obușnuit de setat ultima condiție cu `true`, care se va potrivi întotdeauna. +cond do + 1 + 1 == 3 -> + "Aceasta nu veți vedea niciodată" + 2 * 5 == 12 -> + "Pe mine la fel" + true -> + "Aceasta veți vedea (este else în esență)" +end + +# Blocul `try/catch` se foloște pentru prelucrarea excepțiilor. +# Elixir suportă blocul `after` care se execută în orice caz. +try do + throw(:salut) +catch + mesaj -> "Am primit #{mesaj}." +after + IO.puts("Sunt în blocul after.") +end +#=> Sunt în blocul after. +# "Am primit salut" + +## --------------------------- +## -- Module și Funcții +## --------------------------- + +# Funcții anonime (atenție la punct la apelarea funcției) +square = fn(x) -> x * x end +square.(5) #=> 25 + +# Ele de asemenea aceptă multe clauze și expresii de gardă. +# Expresiile de gardă vă permit să acordați potrivirea șabloanelor, +# ele sunt indicate după cuvîntul cheie `when`: +f = fn + x, y when x > 0 -> x + y + x, y -> x * y +end + +f.(1, 3) #=> 4 +f.(-1, 3) #=> -3 + +# Elixir de asemenea oferă multe funcții incorporate. +# Ele sunt accesibile în scopul curent. +is_number(10) #=> true +is_list("salut") #=> false +elem({1,2,3}, 0) #=> 1 + +# Puteți grupa cîteva funcții într-un modul. În interiorul modulului folosiți `def` +# pentru a defini funcțiile necesare. +defmodule Math do + def sum(a, b) do + a + b + end + + def square(x) do + x * x + end +end + +Math.sum(1, 2) #=> 3 +Math.square(3) #=> 9 + +# Pentru a compila modulul nostru simplu Math îl salvăm ca `math.ex` și utilizăm `elixirc`. +# în terminal: elixirc math.ex + +# În interiorul modulului putem defini funcții cu `def` și funcții private cu `defp`. +defmodule PrivateMath do + # O funcție definită cu `def` este accesibilă pentru apelare din alte module, + def sum(a, b) do + do_sum(a, b) + end + + # O funcție privată poate fi apelată doar local. + defp do_sum(a, b) do + a + b + end +end + +PrivateMath.sum(1, 2) #=> 3 +PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError) + +# Declarația funcției de asemenea suportă expresii de gardă și multe clauze: +defmodule Geometry do + def area({:rectangle, w, h}) do + w * h + end + + def area({:circle, r}) when is_number(r) do + 3.14 * r * r + end +end + +Geometry.area({:rectangle, 2, 3}) #=> 6 +Geometry.area({:circle, 3}) #=> 28.25999999999999801048 +Geometry.area({:circle, "not_a_number"}) #=> ** (FunctionClauseError) + +# Din cauza variabilelor imutabile, un rol important îl ocupă funcțiile recursive +defmodule Recursion do + def sum_list([head | tail], acc) do + sum_list(tail, acc + head) + end + + def sum_list([], acc) do + acc + end +end + +Recursion.sum_list([1,2,3], 0) #=> 6 + +# Modulele în Elixir suportă atribute, există atribute incorporate și +# puteți adăuga altele. +defmodule MyMod do + @moduledoc """ + Este un atribut incorporat + """ + + @my_data 100 # Acesta e atributul nostru + IO.inspect(@my_data) #=> 100 +end + +# Operatorul |> permite transferarea rezultatului unei expresii din stînga +# ca primul argument al unei funcții din dreapta. +Range.new(1,10) +|> Enum.map(fn x -> x * x end) +|> Enum.filter(fn x -> rem(x, 2) == 0 end) +#=> [4, 16, 36, 64, 100] + +## --------------------------- +## -- Structuri și Excepții +## --------------------------- + +# Structurile sunt extensii a dicționarelor ce au valori implicite, +# verificări în timpul compilării și polimorfism +defmodule Person do + defstruct name: nil, age: 0, height: 0 +end + +joe_info = %Person{ name: "Joe", age: 30, height: 180 } +#=> %Person{age: 30, height: 180, name: "Joe"} + +# Acesarea cîmpului din structură +joe_info.name #=> "Joe" + +# Actualizarea valorii cîmpului +older_joe_info = %{ joe_info | age: 31 } +#=> %Person{age: 31, height: 180, name: "Joe"} + +# Blocul `try` cu cuvîntul cheie `rescue` e folosit pentru a prinde excepții +try do + raise "o eroare" +rescue + RuntimeError -> "a fost prinsă o eroare runtime" + _error -> "aici vor fi prinse toate erorile" +end +#=> "a fost prinsă o eroare runtime" + +# Toate excepțiile au un mesaj +try do + raise "o eroare" +rescue + x in [RuntimeError] -> + x.message +end +#=> "o eroare" + +## --------------------------- +## -- Concurența +## --------------------------- + +# Concurența în Elixir se bazează pe modelul actor. Pentru a scrie programe +# concurente avem nevoie de trei lucruri: +# 1. Crearea proceselor +# 2. Trimiterea mesajelor +# 3. Primirea mesajelor + +# Un nou proces se crează folosind funcția `spawn`, care primește o funcție +# ca argument. +f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245> +spawn(f) #=> #PID<0.40.0> + +# `spawn` întoarce identificatorul procesului pid, îl puteți folosi pentru +# a trimite mesaje procesului. Mesajele se transmit folosind operatorul `send`. +# Pentru primirea mesajelor se folosește mecanismul `receive`: + +# Blocul `receive do` este folosit pentru așteptarea mesajelor și prelucrarea lor +# cînd au fost primite. Blocul `receive do` va procesa doar un singur mesaj primit. +# Pentru a procesa mai multe mesaje, funcția cu blocul `receive do` trebuie +# recursiv să se auto apeleze. + +defmodule Geometry do + def area_loop do + receive do + {:rectangle, w, h} -> + IO.puts("Aria = #{w * h}") + area_loop() + {:circle, r} -> + IO.puts("Aria = #{3.14 * r * r}") + area_loop() + end + end +end + +# Compilați modulul și creați un proces +pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0> +# Un alt mod +pid = spawn(Geometry, :area_loop, []) + +# Trimiteți un mesaj către `pid` care se va potrivi cu un șablon din blocul `receive` +send pid, {:rectangle, 2, 3} +#=> Aria = 6 +# {:rectangle,2,3} + +send pid, {:circle, 2} +#=> Aria = 12.56000000000000049738 +# {:circle,2} + +# Interpretatorul este de asemenea un proces, puteți folosi `self` +# pentru a primi identificatorul de proces: +self() #=> #PID<0.27.0> + +## --------------------------- +## -- Agenții +## --------------------------- + +# Un agent este un proces care urmărește careva valori ce se schimbă. + +# Creați un agent cu `Agent.start_link`, transmițînd o funcție. +# Stare inițială a agentului va fi rezultatul funcției. +{ok, my_agent} = Agent.start_link(fn -> ["roșu", "verde"] end) + +# `Agent.get` primește numele agentului și o `fn` care primește starea curentă +# Orice va întoarce `fn` este ceea ce veți primi înapoi: +Agent.get(my_agent, fn colors -> colors end) #=> ["roșu", "verde"] + +# Actualizați starea agentului în acelaș mod: +Agent.update(my_agent, fn colors -> ["albastru" | colors] end) +``` + +## Link-uri utile + +* [Primii pași](http://elixir-lang.org/getting-started/introduction.html) de pe [situl Elixir](http://elixir-lang.org) +* [Documentația oficială Elixir](http://elixir-lang.org/docs/master/) +* [Un mic conspect pe Elixir](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf) +* [Cartea "Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) de Dave Thomas +* [Cartea "Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) de Fred Hebert +* [Cartea "Programming Erlang: Software for a Concurrent World"](https://pragprog.com/book/jaerlang2/programming-erlang) de Joe Armstrong diff --git a/ru-ru/markdown-ru.html.markdown b/ru-ru/markdown-ru.html.markdown index ff7a0cc3..3e20b5d5 100644 --- a/ru-ru/markdown-ru.html.markdown +++ b/ru-ru/markdown-ru.html.markdown @@ -36,7 +36,7 @@ lang: ru-ru Markdown является надмножеством HTML, поэтому любой HTML-файл является корректным документом Markdown. - ```markdown + ```md <!-- Это позволяет использовать напрямую любые элементы HTML-разметки, такие, например, как этот комментарий. Встроенные в документ HTML-элементы не затрагиваются парсером Markdown diff --git a/ruby.html.markdown b/ruby.html.markdown index 4bc872da..2f4d0934 100644 --- a/ruby.html.markdown +++ b/ruby.html.markdown @@ -16,19 +16,20 @@ contributors: - ["Persa Zula", "http://persazula.com"] - ["Jake Faris", "https://github.com/farisj"] - ["Corey Ward", "https://github.com/coreyward"] + - ["Jannik Siebert", "https://github.com/janniks"] --- ```ruby # This is a comment # In Ruby, (almost) everything is an object. -# This includes numbers… +# This includes numbers... 3.class #=> Integer -# …strings… +# ...and strings... "Hello".class #=> String -# …even methods! +# ...and even methods! "Hello".method(:class).class #=> Method # Some basic arithmetic @@ -67,7 +68,7 @@ false.class #=> FalseClass 1 != 1 #=> false 2 != 1 #=> true -# apart from false itself, nil is the only other 'falsey' value +# Apart from false itself, nil is the only other 'falsey' value !!nil #=> false !!false #=> false @@ -111,33 +112,33 @@ placeholder = 'use string interpolation' 'hello ' + 3.to_s #=> "hello 3" "hello #{3}" #=> "hello 3" -# Combine strings and operators +# ...or combine strings and operators 'hello ' * 3 #=> "hello hello hello " -# Append to string +# ...or append to string 'hello' << ' world' #=> "hello world" -# print to the output with a newline at the end +# You can print to the output with a newline at the end puts "I'm printing!" #=> I'm printing! #=> nil -# print to the output without a newline +# ...or print to the output without a newline print "I'm printing!" -#=> I'm printing! => nil +#=> "I'm printing!" => nil # Variables x = 25 #=> 25 x #=> 25 -# Note that assignment returns the value assigned -# This means you can do multiple assignment: +# Note that assignment returns the value assigned. +# This means you can do multiple assignment. x = y = 10 #=> 10 x #=> 10 y #=> 10 -# By convention, use snake_case for variable names +# By convention, use snake_case for variable names. snake_case = true # Use descriptive variable names @@ -146,7 +147,7 @@ m = '/bad/name/' # Symbols are immutable, reusable constants represented internally by an # integer value. They're often used instead of strings to efficiently convey -# specific, meaningful values +# specific, meaningful values. :pending.class #=> Symbol @@ -158,82 +159,82 @@ status == 'pending' #=> false status == :approved #=> false -Strings can be converted into symbols and vice versa: - +# Strings can be converted into symbols and vice versa. status.to_s #=> "pending" "argon".to_sym #=> :argon # Arrays -# This is an array +# This is an array. array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5] -# Arrays can contain different types of items - +# Arrays can contain different types of items. [1, 'hello', false] #=> [1, "hello", false] -# Arrays can be indexed -# From the front +# Arrays can be indexed. +# From the front... array[0] #=> 1 array.first #=> 1 array[12] #=> nil -# Like arithmetic, [var] access -# is just syntactic sugar -# for calling a method [] on an object -array.[] 0 #=> 1 -array.[] 12 #=> nil - -# From the end +# ...or from the back... array[-1] #=> 5 array.last #=> 5 -# With a start index and length +# ...or with a start index and length... array[2, 3] #=> [3, 4, 5] -# Reverse an Array +# ...or with a range... +array[1..3] #=> [2, 3, 4] + +# You can reverse an Array. a = [1,2,3] a.reverse! #=> [3,2,1] -# Or with a range -array[1..3] #=> [2, 3, 4] +# Like arithmetic, [var] access is just syntactic sugar +# for calling a method '[]' on an object. +array.[] 0 #=> 1 +array.[] 12 #=> nil -# Add to an array like this +# You can add to an array... array << 6 #=> [1, 2, 3, 4, 5, 6] # Or like this array.push(6) #=> [1, 2, 3, 4, 5, 6] -# Check if an item exists in an array +# ...and check if an item exists in an array array.include?(1) #=> true # Hashes are Ruby's primary dictionary with key/value pairs. -# Hashes are denoted with curly braces: +# Hashes are denoted with curly braces. hash = { 'color' => 'green', 'number' => 5 } hash.keys #=> ['color', 'number'] -# Hashes can be quickly looked up by key: -hash['color'] #=> 'green' +# Hashes can be quickly looked up by key. +hash['color'] #=> "green" hash['number'] #=> 5 -# Asking a hash for a key that doesn't exist returns nil: +# Asking a hash for a key that doesn't exist returns nil. hash['nothing here'] #=> nil -# When using symbols for keys in a hash, you can use this alternate syntax: +# When using symbols for keys in a hash, you can use an alternate syntax. -new_hash = { defcon: 3, action: true } +hash = { :defcon => 3, :action => true } +hash.keys #=> [:defcon, :action] -new_hash.keys #=> [:defcon, :action] +hash = { defcon: 3, action: true } +hash.keys #=> [:defcon, :action] # Check existence of keys and values in hash -new_hash.key?(:defcon) #=> true -new_hash.value?(3) #=> true +hash.key?(:defcon) #=> true +hash.value?(3) #=> true -# Tip: Both Arrays and Hashes are Enumerable -# They share a lot of useful methods such as each, map, count, and more +# Tip: Both Arrays and Hashes are Enumerable! +# They share a lot of useful methods such as each, map, count, and more. # Control structures +# Conditionals if true 'if statement' elsif false @@ -242,28 +243,26 @@ else 'else, also optional' end - +# Loops # In Ruby, traditional `for` loops aren't very common. Instead, these -# basic loops are implemented using enumerable, which hinges on `each`: - +# basic loops are implemented using enumerable, which hinges on `each`. (1..5).each do |counter| puts "iteration #{counter}" end -# Which is roughly equivalent to this, which is unusual to see in Ruby: - +# Which is roughly equivalent to the following, which is unusual to see in Ruby. for counter in 1..5 puts "iteration #{counter}" end -# The `do |variable| ... end` construct above is called a “block”. Blocks are similar +# The `do |variable| ... end` construct above is called a 'block'. Blocks are similar # to lambdas, anonymous functions or closures in other programming languages. They can -# be passed around as objects, called, or attached as methods. +# be passed around as objects, called, or attached as methods. # -# The "each" method of a range runs the block once for each element of the range. +# The 'each' method of a range runs the block once for each element of the range. # The block is passed a counter as a parameter. -# You can also surround blocks in curly brackets: +# You can also surround blocks in curly brackets. (1..5).each { |counter| puts "iteration #{counter}" } # The contents of data structures can also be iterated using each. @@ -274,8 +273,8 @@ hash.each do |key, value| puts "#{key} is #{value}" end -# If you still need an index you can use "each_with_index" and define an index -# variable +# If you still need an index you can use 'each_with_index' and define an index +# variable. array.each_with_index do |element, index| puts "#{element} is number #{index} in the array" end @@ -291,9 +290,9 @@ end #=> iteration 4 #=> iteration 5 -# There are a bunch of other helpful looping functions in Ruby, -# for example "map", "reduce", "inject", the list goes on. Map, -# for instance, takes the array it's looping over, does something +# There are a bunch of other helpful looping functions in Ruby. +# For example: 'map', 'reduce', 'inject', the list goes on. +# Map, for instance, takes the array it's looping over, does something # to it as defined in your block, and returns an entirely new array. array = [1,2,3,4,5] doubled = array.map do |element| @@ -304,6 +303,7 @@ puts doubled puts array #=> [1,2,3,4,5] +# Case construct grade = 'B' case grade @@ -322,7 +322,7 @@ else end #=> "Better luck next time" -# cases can also use ranges +# Cases can also use ranges grade = 82 case grade when 90..100 @@ -334,9 +334,9 @@ else end #=> "OK job" -# exception handling: +# Exception handling begin - # code here that might raise an exception + # Code here that might raise an exception raise NoMemoryError, 'You ran out of memory.' rescue NoMemoryError => exception_variable puts 'NoMemoryError was raised', exception_variable @@ -354,10 +354,10 @@ def double(x) x * 2 end -# Methods (and blocks) implicitly return the value of the last statement +# Methods (and blocks) implicitly return the value of the last statement. double(2) #=> 4 -# Parentheses are optional where the interpretation is unambiguous +# Parentheses are optional where the interpretation is unambiguous. double 3 #=> 6 double double 3 #=> 12 @@ -366,15 +366,14 @@ def sum(x, y) x + y end -# Method arguments are separated by a comma +# Method arguments are separated by a comma. sum 3, 4 #=> 7 sum sum(3, 4), 5 #=> 12 # yield -# All methods have an implicit, optional block parameter -# it can be called with the 'yield' keyword - +# All methods have an implicit, optional block parameter. +# Tt can be called with the 'yield' keyword. def surround puts '{' yield @@ -383,45 +382,43 @@ end surround { puts 'hello world' } -# { -# hello world -# } +#=> { +#=> hello world +#=> } - -# Blocks can be converted into a `proc` object, which wraps the block +# Blocks can be converted into a 'proc' object, which wraps the block # and allows it to be passed to another method, bound to a different scope, # or manipulated otherwise. This is most common in method parameter lists, -# where you frequently see a trailing `&block` parameter that will accept -# the block, if one is given, and convert it to a `Proc`. The naming here is -# convention; it would work just as well with `&pineapple`: +# where you frequently see a trailing '&block' parameter that will accept +# the block, if one is given, and convert it to a 'Proc'. The naming here is +# convention; it would work just as well with '&pineapple'. def guests(&block) block.class #=> Proc block.call(4) end -# The `call` method on the Proc is similar to calling `yield` when a block is -# present. The arguments passed to `call` will be forwarded to the block as arugments: +# The 'call' method on the Proc is similar to calling 'yield' when a block is +# present. The arguments passed to 'call' will be forwarded to the block as arugments. guests { |n| "You have #{n} guests." } # => "You have 4 guests." -# You can pass a list of arguments, which will be converted into an array -# That's what splat operator ("*") is for +# You can pass a list of arguments, which will be converted into an array. +# That's what splat operator ("*") is for. def guests(*array) array.each { |guest| puts guest } end # Destructuring -# Ruby will automatically destructure arrays on assignment to multiple variables: +# Ruby will automatically destructure arrays on assignment to multiple variables. a, b, c = [1, 2, 3] a #=> 1 b #=> 2 c #=> 3 # In some cases, you will want to use the splat operator: `*` to prompt destructuring -# of an array into a list: - +# of an array into a list. ranked_competitors = ["John", "Sally", "Dingus", "Moe", "Marcy"] def best(first, second, third) @@ -430,7 +427,7 @@ end best *ranked_competitors.first(3) #=> Winners are John, Sally, and Dingus. -# The splat operator can also be used in parameters: +# The splat operator can also be used in parameters. def best(first, second, third, *others) puts "Winners are #{first}, #{second}, and #{third}." puts "There were #{others.count} other participants." @@ -440,21 +437,23 @@ best *ranked_competitors #=> Winners are John, Sally, and Dingus. #=> There were 2 other participants. -# By convention, all methods that return booleans end with a question mark -5.even? # false -5.odd? # true +# By convention, all methods that return booleans end with a question mark. +5.even? #=> false +5.odd? #=> true -# And if a method ends with an exclamation mark, it does something destructive +# By convention, if a method name ends with an exclamation mark, it does something destructive # like mutate the receiver. Many methods have a ! version to make a change, and -# a non-! version to just return a new changed version +# a non-! version to just return a new changed version. company_name = "Dunder Mifflin" company_name.upcase #=> "DUNDER MIFFLIN" company_name #=> "Dunder Mifflin" -company_name.upcase! # we're mutating company_name this time! +# We're mutating company_name this time. +company_name.upcase! #=> "DUNDER MIFFLIN" company_name #=> "DUNDER MIFFLIN" +# Classes -# Define a class with the class keyword +# You can define a class with the 'class' keyword. class Human # A class variable. It is shared by all instances of this class. @@ -462,7 +461,7 @@ class Human # Basic initializer def initialize(name, age = 0) - # Assign the argument to the "name" instance variable for the instance + # Assign the argument to the 'name' instance variable for the instance. @name = name # If no age given, we will fall back to the default in the arguments list. @age = age @@ -478,10 +477,10 @@ 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 attr_accessor method as follows. attr_accessor :name - # Getter/setter methods can also be created individually like this + # Getter/setter methods can also be created individually like this. attr_reader :name attr_writer :name @@ -496,13 +495,11 @@ class Human end end - -# Instantiate a class +# Instantiating of a class jim = Human.new('Jim Halpert') - dwight = Human.new('Dwight K. Schrute') -# Let's call a couple of methods +# You can call the methods of the generated object. jim.species #=> "H. sapiens" jim.name #=> "Jim Halpert" jim.name = "Jim Halpert II" #=> "Jim Halpert II" @@ -510,30 +507,30 @@ jim.name #=> "Jim Halpert II" dwight.species #=> "H. sapiens" dwight.name #=> "Dwight K. Schrute" -# Call the class method +# Calling of a class method Human.say('Hi') #=> "Hi" # Variable's scopes are defined by the way we name them. -# Variables that start with $ have global scope +# Variables that start with $ have global scope. $var = "I'm a global var" defined? $var #=> "global-variable" -# Variables that start with @ have instance scope +# Variables that start with @ have instance scope. @var = "I'm an instance var" defined? @var #=> "instance-variable" -# Variables that start with @@ have class scope +# Variables that start with @@ have class scope. @@var = "I'm a class var" defined? @@var #=> "class variable" -# Variables that start with a capital letter are constants +# Variables that start with a capital letter are constants. Var = "I'm a constant" defined? Var #=> "constant" -# Class is also an object in ruby. So class can have instance variables. -# Class variable is shared among the class and all of its descendants. +# Class is also an object in ruby. So a class can have instance variables. +# A class variable is shared among the class and all of its descendants. -# base class +# Base class class Human @@foo = 0 @@ -546,18 +543,17 @@ class Human end end -# derived class +# Derived class class Worker < Human end -Human.foo # 0 -Worker.foo # 0 - -Human.foo = 2 # 2 -Worker.foo # 2 +Human.foo #=> 0 +Worker.foo #=> 0 -# Class instance variable is not shared by the class's descendants. +Human.foo = 2 +Worker.foo #=> 2 +# A class instance variable is not shared by the class's descendants. class Human @bar = 0 @@ -573,8 +569,8 @@ end class Doctor < Human end -Human.bar # 0 -Doctor.bar # nil +Human.bar #=> 0 +Doctor.bar #=> nil module ModuleExample def foo @@ -582,9 +578,8 @@ module ModuleExample end end -# Including modules binds their methods to the class instances -# Extending modules binds their methods to the class itself - +# Including modules binds their methods to the class instances. +# Extending modules binds their methods to the class itself. class Person include ModuleExample end @@ -593,13 +588,12 @@ class Book extend ModuleExample end -Person.foo # => NoMethodError: undefined method `foo' for Person:Class -Person.new.foo # => 'foo' -Book.foo # => 'foo' -Book.new.foo # => NoMethodError: undefined method `foo' +Person.foo #=> NoMethodError: undefined method `foo' for Person:Class +Person.new.foo #=> "foo" +Book.foo #=> "foo" +Book.new.foo #=> NoMethodError: undefined method `foo' # Callbacks are executed when including and extending a module - module ConcernExample def self.included(base) base.extend(ClassMethods) @@ -623,10 +617,10 @@ class Something include ConcernExample end -Something.bar # => 'bar' -Something.qux # => NoMethodError: undefined method `qux' -Something.new.bar # => NoMethodError: undefined method `bar' -Something.new.qux # => 'qux' +Something.bar #=> "bar" +Something.qux #=> NoMethodError: undefined method `qux' +Something.new.bar #=> NoMethodError: undefined method `bar' +Something.new.qux #=> "qux" ``` ## Additional resources diff --git a/toml.html.markdown b/toml.html.markdown index 39caaa23..814e57e7 100755 --- a/toml.html.markdown +++ b/toml.html.markdown @@ -12,7 +12,7 @@ It is an alternative to YAML and JSON. It aims to be more human friendly than JS Be warned, TOML's spec is still changing a lot. Until it's marked as 1.0, you should assume that it is unstable and act accordingly. This document follows TOML v0.4.0. -```toml +``` # Comments in TOML look like this. ################ diff --git a/tr-tr/c++-tr.html.markdown b/tr-tr/c++-tr.html.markdown index a1318876..f9f22a1d 100644 --- a/tr-tr/c++-tr.html.markdown +++ b/tr-tr/c++-tr.html.markdown @@ -27,12 +27,12 @@ tipten bağımsızlık, exception'lar ve sınıflar gibi yüksek-seviyeli özell Bu hız ve kullanışlılık C++'ı en çok kullanılan dillerden biri yapar. ```c++ -////////////////// +////////////////////// // C ile karşılaştırma -////////////////// +////////////////////// // C++ _neredeyse_ C'nin bir üstkümesidir, değişken tanımı, basit tipleri -ve fonksiyonları için temelde aynı sözdizimini paylaşır. +// ve fonksiyonları için temelde aynı sözdizimini paylaşır. // Aynı C gibi, programın başlangıç noktası bir integer döndüren // main fonksiyonudur. @@ -105,7 +105,7 @@ int main() //////////////////////////////// // Default fonksiyon argümanları -/////////////////////////////i// +//////////////////////////////// // Eğer çağırıcı tarafından fonksiyona argüman sağlanmamışsa, // fonksiyona default argüman verebilirsin @@ -263,7 +263,7 @@ string retVal = tempObjectFun(); // Bu iki satırda aslında ne oluyor: // - tempObjectFun fonksiyonundan bir string nesnesi dönüyor // - dönmüş olan nesneyle yeni bir string oluşturuyor -/ - dönmüş olan nesne yok ediliyor +// - dönmüş olan nesne yok ediliyor // İşte bu dönen nesneye geçici nesne denir. Geçici nesneler fonksiyon nesne // döndürdüğünde oluşturulur ve ifade işini bitirdiğinde yok edilir (Aslında, // standard'ın söylediği şey bu ama derleyiciler bu davranışı değiştirmemize @@ -366,7 +366,6 @@ void WritePreferredCarTypeToFile(ECarTypes InputCarType) // Sınıfı tanımla. // Sınıflar genelde header (.h veya .hpp) dosyalarında tanımlanır. class Dog { - // Member variables and functions are private by default. // Üye değişkenler ve fonksiyonlar default olarak private'dir. std::string name; int weight; @@ -548,7 +547,7 @@ int main () { // Şablonlar C++ dilinde tipten bağımsız programlama için kullanılır. // Zaten aşina olduğun tipten bağımsız programlamayla başladık. Bir tip parametresi -alan fonksiyon veya sınıf tanımlamaık için: +// alan fonksiyon veya sınıf tanımlamaık için: template<class T> class Box { public: @@ -801,9 +800,9 @@ sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int, // "Tutma listesi", fonksiyon gövdesinde nelerin, ne şekilde erişilebilir olduğunu tanımlar // Şunlardan biri olabilir: // 1. bir değer : [x] - 2. bir referans : [&x] - 3. mevcut scope içindeki herhangi bir değişkene referans ile [&] - 4. 3 ile aynı, ama değer ile [=] +// 2. bir referans : [&x] +// 3. mevcut scope içindeki herhangi bir değişkene referans ile [&] +// 4. 3 ile aynı, ama değer ile [=] // Mesela: vector<int> dog_ids; // number_of_dogs = 3; @@ -842,9 +841,9 @@ for(auto elem: arr) { // arr dizisinin elemanlarıyla ilgili bir şeyler yap } -///////////////////// +//////////////// // Güzel Şeyler -///////////////////// +//////////////// // C++ dilinin bakış açısı yeni başlayanlar için (hatta dili iyi bilenler için bile) // şaşırtıcı olabilir. diff --git a/tr-tr/markdown-tr.html.markdown b/tr-tr/markdown-tr.html.markdown index b8f11e39..6caba1da 100644 --- a/tr-tr/markdown-tr.html.markdown +++ b/tr-tr/markdown-tr.html.markdown @@ -11,7 +11,7 @@ filename: markdown-tr.md Markdown, 2004 yılında John Gruber tarafından oluşturuldu. Asıl amacı kolay okuma ve yazmayı sağlamakla beraber kolayca HTML (artık bir çok diğer formatlara) dönüşüm sağlamaktır. -```markdown +```md <!-- Markdown, HTML'i kapsar, yani her HTML dosyası geçerli bir Markdown dosyasıdır, bu demektir ki Markdown içerisinde HTML etiketleri kullanabiliriz, örneğin bu yorum elementi, ve markdown işleyicisinde etki etmezler. Fakat, markdown dosyası içerisinde HTML elementi oluşturursanız, diff --git a/uk-ua/java-ua.html.markdown b/uk-ua/java-ua.html.markdown index 1d600400..df642f73 100644 --- a/uk-ua/java-ua.html.markdown +++ b/uk-ua/java-ua.html.markdown @@ -30,7 +30,7 @@ JavaDoc-коментар виглядає так. Використовуєтьс // Імпорт класу ArrayList з пакета java.util import java.util.ArrayList; -// Імпорт усіх класів з пакета java.security +// Імпорт усіх класів з пакета java.security import java.security.*; // Кожний .java файл містить один зовнішній публічний клас, ім’я якого співпадає @@ -99,13 +99,13 @@ public class LearnJava { // Примітка: Java не має беззнакових типів. - // Float — 32-бітне число з рухомою комою одиничної точності за стандартом IEEE 754 + // Float — 32-бітне число з рухомою комою одиничної точності за стандартом IEEE 754 // 2^-149 <= float <= (2-2^-23) * 2^127 float fooFloat = 234.5f; // f або F використовується для позначення того, що змінна має тип float; // інакше трактується як double. - // Double — 64-бітне число з рухомою комою подвійної точності за стандартом IEEE 754 + // Double — 64-бітне число з рухомою комою подвійної точності за стандартом IEEE 754 // 2^-1074 <= x <= (2-2^-52) * 2^1023 double fooDouble = 123.4; @@ -130,13 +130,13 @@ public class LearnJava { // байтів, операції над ними виконуються функціями, які мають клас BigInteger // // BigInteger можна ініціалізувати, використовуючи масив байтів чи рядок. - + BigInteger fooBigInteger = new BigInteger(fooByteArray); // BigDecimal — Незмінні знакові дробові числа довільної точності // - // BigDecimal складається з двох частин: цілого числа довільної точності + // BigDecimal складається з двох частин: цілого числа довільної точності // з немасштабованим значенням та 32-бітного масштабованого цілого числа // // BigDecimal дозволяє розробникам контролювати десяткове округлення. @@ -147,10 +147,10 @@ public class LearnJava { // чи немасштабованим значенням (BigInteger) і масштабованим значенням (int). BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt); - + // Для дотримання заданої точності рекомендується використовувати - // конструктор, який приймає String - + // конструктор, який приймає String + BigDecimal tenCents = new BigDecimal("0.1"); @@ -295,7 +295,7 @@ public class LearnJava { // Виконається 10 разів, fooFor 0->9 } System.out.println("Значення fooFor: " + fooFor); - + // Вихід із вкладеного циклу через мітку outer: for (int i = 0; i < 10; i++) { @@ -306,7 +306,7 @@ public class LearnJava { } } } - + // Цикл For Each // Призначений для перебору масивів та колекцій int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9}; @@ -318,7 +318,7 @@ public class LearnJava { // Оператор вибору Switch Case // Оператор вибору працює з типами даних byte, short, char, int. - // Також працює з переліками Enum, + // Також працює з переліками Enum, // класом String та класами-обгортками примітивних типів: // Character, Byte, Short та Integer. int month = 3; @@ -334,7 +334,7 @@ public class LearnJava { break; } System.out.println("Результат Switch Case: " + monthString); - + // Починаючи з Java 7 і далі, вибір рядкових змінних здійснюється так: String myAnswer = "можливо"; switch(myAnswer) { @@ -398,7 +398,7 @@ public class LearnJava { // toString повертає рядкове представлення об’єкту. System.out.println("Інформація про об’єкт trek: " + trek.toString()); - + // У Java немає синтаксису для явного створення статичних колекцій. // Це можна зробити так: @@ -554,7 +554,7 @@ public interface Digestible { // Можна створити клас, що реалізує обидва інтерфейси. public class Fruit implements Edible, Digestible { - + @Override public void eat() { // ... @@ -694,41 +694,41 @@ public abstract class Mammal() public enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, - THURSDAY, FRIDAY, SATURDAY + THURSDAY, FRIDAY, SATURDAY } // Перелік Day можна використовувати так: public class EnumTest { - + // Змінна того же типу, що й перелік Day day; - + public EnumTest(Day day) { this.day = day; } - + public void tellItLikeItIs() { switch (day) { case MONDAY: - System.out.println("Понеділкі важкі."); + System.out.println("Понеділки важкі."); break; - + case FRIDAY: System.out.println("П’ятниці краще."); break; - - case SATURDAY: + + case SATURDAY: case SUNDAY: System.out.println("Вихідні найліпші."); break; - + default: System.out.println("Середина тижня так собі."); break; } } - + public static void main(String[] args) { EnumTest firstDay = new EnumTest(Day.MONDAY); firstDay.tellItLikeItIs(); // => Понеділки важкі. @@ -737,7 +737,7 @@ public class EnumTest { } } -// Переліки набагато потужніші, ніж тут показано. +// Переліки набагато потужніші, ніж тут показано. // Тіло переліків може містити методи та інші змінні. // Дивіться більше тут: https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html diff --git a/uk-ua/javascript-ua.html.markdown b/uk-ua/javascript-ua.html.markdown index 397b1c5e..6a64a623 100644 --- a/uk-ua/javascript-ua.html.markdown +++ b/uk-ua/javascript-ua.html.markdown @@ -45,7 +45,7 @@ doStuff() 3; // = 3 1.5; // = 1.5 -// Деякі прості арифметичні операції працють так, як ми очікуємо. +// Деякі прості арифметичні операції працюють так, як ми очікуємо. 1 + 1; // = 2 0.1 + 0.2; // = 0.30000000000000004 (а деякі - ні) 8 - 1; // = 7 @@ -106,7 +106,7 @@ null == undefined; // = true // ... але приведення не виконується при === "5" === 5; // = false -null === undefined; // = false +null === undefined; // = false // ... приведення типів може призвести до дивних результатів 13 + !0; // 14 @@ -171,7 +171,7 @@ myArray[3] = "світ"; // Об’єкти в JavaScript схожі на словники або асоціативні масиви в інших мовах var myObj = {key1: "Hello", key2: "World"}; -// Ключі - це рядки, але лапки не обов’язкі, якщо ключ задовольняє +// Ключі - це рядки, але лапки не обов’язкові, якщо ключ задовольняє // правилам формування назв змінних. Значення можуть бути будь-яких типів. var myObj = {myKey: "myValue", "my other key": 4}; @@ -258,7 +258,7 @@ function myFunction(thing) { return thing.toUpperCase(); } myFunction("foo"); // = "FOO" - + // Зверніть увагу, що значення яке буде повернено, повинно починатися на тому ж // рядку, що і ключове слово return, інакше завжди буде повертатися значення undefined // через автоматичну вставку крапки з комою @@ -332,7 +332,7 @@ var myObj = { }; myObj.myFunc(); // = "Hello, world!" -// Функції, що прикріплені до об’єктів мають доступ до поточного об’єкта за +// Функції, що прикріплені до об’єктів мають доступ до поточного об’єкта за // допомогою ключового слова this. myObj = { myString: "Hello, world!", @@ -348,7 +348,7 @@ myObj.myFunc(); // = "Hello, world!" var myFunc = myObj.myFunc; myFunc(); // = undefined -// Функція може бути присвоєна іншому об’єкту. Тоді вона матиме доступ до +// Функція може бути присвоєна іншому об’єкту. Тоді вона матиме доступ до // цього об’єкта через this var myOtherFunc = function() { return this.myString.toUpperCase(); @@ -371,7 +371,7 @@ Math.min(42, 6, 27); // = 6 Math.min([42, 6, 27]); // = NaN (Ой-ой!) Math.min.apply(Math, [42, 6, 27]); // = 6 -// Але call і apply — тимчасові. Коли ми хочемо зв’язати функцію і об’єкт +// Але call і apply — тимчасові. Коли ми хочемо зв’язати функцію і об’єкт // використовують bind var boundFunc = anotherFunc.bind(myObj); boundFunc(" Hello!"); // = "Hello world, Hello!" @@ -475,7 +475,7 @@ if (Object.create === undefined) { // не перезаписуємо метод // Створюємо правильний конструктор з правильним прототипом var Constructor = function(){}; Constructor.prototype = proto; - + return new Constructor(); } } diff --git a/uk-ua/python-ua.html.markdown b/uk-ua/python-ua.html.markdown new file mode 100644 index 00000000..2406678d --- /dev/null +++ b/uk-ua/python-ua.html.markdown @@ -0,0 +1,818 @@ +--- +language: python +lang: uk-ua +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: + - ["Oleg Gromyak", "https://github.com/ogroleg"] +filename: learnpython-ua.py +--- + +Мову Python створив Гвідо ван Россум на початку 90-х. Наразі це одна з +найбільш популярних мов. Я закохався у Python завдяки простому і зрозумілому +синтаксису. Це майже як виконуваний псевдокод. + +З вдячністю чекаю ваших відгуків: [@louiedinh](http://twitter.com/louiedinh) +або louiedinh [at] [поштовий сервіс від Google] + +Примітка: Ця стаття стосується Python 2.7, проте має працювати і +у інших версіях Python 2.x. Python 2.7 підходить до кінця свого терміну, +його підтримку припинять у 2020, тож наразі краще починати вивчення Python +з версії 3.x. +Аби вивчити Python 3.x, звертайтесь до статті по Python 3. + +```python +# Однорядкові коментарі починаються з символу решітки. + +""" Текст, що займає декілька рядків, + може бути записаний з використанням 3 знаків " і + зазвичай використовується у якості + вбудованої документації +""" + +#################################################### +## 1. Примітивні типи даних та оператори +#################################################### + +# У вас є числа +3 # => 3 + +# Математика працює досить передбачувано +1 + 1 # => 2 +8 - 1 # => 7 +10 * 2 # => 20 +35 / 5 # => 7 + +# А ось з діленням все трохи складніше. Воно цілочисельне і результат +# автоматично округлюється у меншу сторону. +5 / 2 # => 2 + +# Аби правильно ділити, спершу варто дізнатися про числа +# з плаваючою комою. +2.0 # Це число з плаваючою комою +11.0 / 4.0 # => 2.75 ох... Так набагато краще + +# Результат цілочисельного ділення округлюється у меншу сторону +# як для додатніх, так і для від'ємних чисел. +5 // 3 # => 1 +5.0 // 3.0 # => 1.0 # Працює і для чисел з плаваючою комою +-5 // 3 # => -2 +-5.0 // 3.0 # => -2.0 + +# Зверніть увагу, що ми також можемо імпортувати модуль для ділення, +# див. розділ Модулі +# аби звичне ділення працювало при використанні лише '/'. +from __future__ import division + +11 / 4 # => 2.75 ...звичне ділення +11 // 4 # => 2 ...цілочисельне ділення + +# Залишок від ділення +7 % 3 # => 1 + +# Піднесення до степеня +2 ** 4 # => 16 + +# Приорітет операцій вказується дужками +(1 + 3) * 2 # => 8 + +# Логічні оператори +# Зверніть увагу: ключові слова «and» і «or» чутливі до регістру букв +True and False # => False +False or True # => True + +# Завважте, що логічні оператори також використовуються і з цілими числами +0 and 2 # => 0 +-5 or 0 # => -5 +0 == False # => True +2 == True # => False +1 == True # => True + +# Для заперечення використовується not +not True # => False +not False # => True + +# Рівність — це == +1 == 1 # => True +2 == 1 # => False + +# Нерівність — це != +1 != 1 # => False +2 != 1 # => True + +# Ще трохи порівнянь +1 < 10 # => True +1 > 10 # => False +2 <= 2 # => True +2 >= 2 # => True + +# Порівняння можуть бути записані ланцюжком! +1 < 2 < 3 # => True +2 < 3 < 2 # => False + +# Рядки позначаються символом " або ' +"Це рядок." +'Це теж рядок.' + +# І рядки також можна додавати! +"Привіт " + "світ!" # => "Привіт світ!" +# Рядки можна додавати і без '+' +"Привіт " "світ!" # => "Привіт світ!" + +# ... або множити +"Привіт" * 3 # => "ПривітПривітПривіт" + +# З рядком можна працювати як зі списком символів +"Це рядок"[0] # => 'Ц' + +# Ви можете дізнатися довжину рядка +len("Це рядок") # => 8 + +# Символ % використовується для форматування рядків, наприклад: +"%s можуть бути %s" % ("рядки", "інтерпольовані") + +# Новий спосіб форматування рядків — використання методу format. +# Це бажаний спосіб. +"{} є {}".format("Це", "заповнювач") +"{0} можуть бути {1}".format("рядки", "форматовані") +# Якщо ви не хочете рахувати, то можете скористатися ключовими словами. +"{name} хоче з'істи {food}".format(name="Боб", food="лазанью") + +# None - це об'єкт +None # => None + +# Не використовуйте оператор рівності '=='' для порівняння +# об'єктів з None. Використовуйте для цього «is» +"etc" is None # => False +None is None # => True + +# Оператор 'is' перевіряє ідентичність об'єктів. Він не +# дуже корисний при роботі з примітивними типами, проте +# незамінний при роботі з об'єктами. + +# None, 0 і порожні рядки/списки рівні False. +# Всі інші значення рівні True +bool(0) # => False +bool("") # => False + + +#################################################### +## 2. Змінні та колекції +#################################################### + +# В Python є оператор print +print "Я Python. Приємно познайомитись!" # => Я Python. Приємно познайомитись! + +# Отримати дані з консолі просто +input_string_var = raw_input( + "Введіть щось: ") # Повертає дані у вигляді рядка +input_var = input("Введіть щось: ") # Працює з даними як з кодом на python +# Застереження: будьте обережні при використанні методу input() + +# Оголошувати змінні перед ініціалізацією не потрібно. +some_var = 5 # За угодою використовується нижній_регістр_з_підкресленнями +some_var # => 5 + +# При спробі доступу до неініціалізованої змінної +# виникне виняткова ситуація. +# Див. розділ Потік управління, аби дізнатись про винятки більше. +some_other_var # Помилка в імені + +# if може використовуватися як вираз +# Такий запис еквівалентний тернарному оператору '?:' у мові С +"yahoo!" if 3 > 2 else 2 # => "yahoo!" + +# Списки зберігають послідовності +li = [] +# Можна одразу створити заповнений список +other_li = [4, 5, 6] + +# Об'єкти додаються у кінець списку за допомогою методу append +li.append(1) # li тепер дорівнює [1] +li.append(2) # li тепер дорівнює [1, 2] +li.append(4) # li тепер дорівнює [1, 2, 4] +li.append(3) # li тепер дорівнює [1, 2, 4, 3] +# І видаляються з кінця методом pop +li.pop() # => повертає 3 і li стає рівним [1, 2, 4] +# Повернемо елемент назад +li.append(3) # li тепер знову дорівнює [1, 2, 4, 3] + +# Поводьтесь зі списком як зі звичайним масивом +li[0] # => 1 +# Присвоюйте нові значення вже ініціалізованим індексам за допомогою = +li[0] = 42 +li[0] # => 42 +li[0] = 1 # Зверніть увагу: повертаємось до попереднього значення +# Звертаємось до останнього елементу +li[-1] # => 3 + +# Спроба вийти за границі масиву призводить до помилки в індексі +li[4] # помилка в індексі + +# Можна звертатися до діапазону, використовуючи так звані зрізи +# (Для тих, хто любить математику: це називається замкнуто-відкритий інтервал). +li[1:3] # => [2, 4] +# Опускаємо початок +li[2:] # => [4, 3] +# Опускаємо кінець +li[:3] # => [1, 2, 4] +# Вибираємо кожен другий елемент +li[::2] # => [1, 4] +# Перевертаємо список +li[::-1] # => [3, 4, 2, 1] +# Використовуйте суміш вищеназваного для більш складних зрізів +# li[початок:кінець:крок] + +# Видаляємо довільні елементи зі списку оператором del +del li[2] # li тепер [1, 2, 3] + +# Ви можете додавати списки +li + other_li # => [1, 2, 3, 4, 5, 6] +# Зверніть увагу: значення li та other_li при цьому не змінились. + +# Поєднувати списки можна за допомогою методу extend +li.extend(other_li) # Тепер li дорівнює [1, 2, 3, 4, 5, 6] + +# Видалити перше входження значення +li.remove(2) # Тепер li дорівнює [1, 3, 4, 5, 6] +li.remove(2) # Помилка значення, оскільки у списку li немає 2 + +# Вставити елемент за вказаним індексом +li.insert(1, 2) # li знову дорівнює [1, 2, 3, 4, 5, 6] + +# Отримати індекс першого знайденого елементу +li.index(2) # => 1 +li.index(7) # Помилка значення, оскільки у списку li немає 7 + +# Перевірити елемент на входження у список можна оператором in +1 in li # => True + +# Довжина списку обчислюється за допомогою функції len +len(li) # => 6 + +# Кортежі схожі на списки, лише незмінні +tup = (1, 2, 3) +tup[0] # => 1 +tup[0] = 3 # Виникає помилка типу + +# Все те ж саме можна робити і з кортежами +len(tup) # => 3 +tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6) +tup[:2] # => (1, 2) +2 in tup # => True + +# Ви можете розпаковувати кортежі (або списки) у змінні +a, b, c = (1, 2, 3) # a == 1, b == 2 и c == 3 +d, e, f = 4, 5, 6 # дужки можна опустити +# Кортежі створюються за замовчуванням, якщо дужки опущено +g = 4, 5, 6 # => (4, 5, 6) +# Дивіться, як легко обміняти значення двох змінних +e, d = d, e # тепер d дорівнює 5, а e дорівнює 4 + +# Словники містять асоціативні масиви +empty_dict = {} +# Ось так описується попередньо заповнений словник +filled_dict = {"one": 1, "two": 2, "three": 3} + +# Значення можна отримати так само, як і зі списку +filled_dict["one"] # => 1 + +# Можна отримати всі ключі у виді списку за допомогою методу keys +filled_dict.keys() # => ["three", "two", "one"] +# Примітка: збереження порядку ключів у словників не гарантується +# Ваші результати можуть не співпадати з цими. + +# Можна отримати і всі значення у вигляді списку, використовуйте метод values +filled_dict.values() # => [3, 2, 1] +# Те ж зауваження щодо порядку ключів діє і тут + +# Отримуйте всі пари ключ-значення у вигляді списку кортежів +# за допомогою "items()" +filled_dict.items() # => [("one", 1), ("two", 2), ("three", 3)] + +# За допомогою оператору in можна перевіряти ключі на входження у словник +"one" in filled_dict # => True +1 in filled_dict # => False + +# Спроба отримати значення за неіснуючим ключем викине помилку ключа +filled_dict["four"] # помилка ключа + +# Аби уникнути цього, використовуйте метод get() +filled_dict.get("one") # => 1 +filled_dict.get("four") # => None +# Метод get також приймає аргумент за замовчуванням, значення якого буде +# повернуто при відсутності вказаного ключа +filled_dict.get("one", 4) # => 1 +filled_dict.get("four", 4) # => 4 +# Зверніть увагу, що filled_dict.get("four") все ще => None +# (get не встановлює значення елементу словника) + +# Присвоюйте значення ключам так само, як і в списках +filled_dict["four"] = 4 # тепер filled_dict["four"] => 4 + +# Метод setdefault() вставляє пару ключ-значення лише +# за відсутності такого ключа +filled_dict.setdefault("five", 5) # filled_dict["five"] повертає 5 +filled_dict.setdefault("five", 6) # filled_dict["five"] все ще повертає 5 + + +# Множини містять... ну, загалом, множини +# (які схожі на списки, проте в них не може бути елементів, які повторюються) +empty_set = set() +# Ініціалізація множини набором значень +some_set = set([1,2,2,3,4]) # some_set тепер дорівнює set([1, 2, 3, 4]) + +# Порядок не гарантовано, хоча інколи множини виглядають відсортованими +another_set = set([4, 3, 2, 2, 1]) # another_set тепер set([1, 2, 3, 4]) + +# Починаючи з Python 2.7, ви можете використовувати {}, аби створити множину +filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4} + +# Додавання нових елементів у множину +filled_set.add(5) # filled_set тепер дорівнює {1, 2, 3, 4, 5} + +# Перетин множин: & +other_set = {3, 4, 5, 6} +filled_set & other_set # => {3, 4, 5} + +# Об'єднання множин: | +filled_set | other_set # => {1, 2, 3, 4, 5, 6} + +# Різниця множин: - +{1,2,3,4} - {2,3,5} # => {1, 4} + +# Симетрична різниця множин: ^ +{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5} + +# Перевіряємо чи множина зліва є надмножиною множини справа +{1, 2} >= {1, 2, 3} # => False + +# Перевіряємо чи множина зліва є підмножиною множини справа +{1, 2} <= {1, 2, 3} # => True + +# Перевірка на входження у множину: in +2 in filled_set # => True +10 in filled_set # => False + + +#################################################### +## 3. Потік управління +#################################################### + +# Для початку створимо змінну +some_var = 5 + +# Так виглядає вираз if. Відступи у python дуже важливі! +# результат: «some_var менше, ніж 10» +if some_var > 10: + print("some_var набагато більше, ніж 10.") +elif some_var < 10: # Вираз elif є необов'язковим. + print("some_var менше, ніж 10.") +else: # Це теж необов'язково. + print("some_var дорівнює 10.") + + +""" +Цикли For проходять по спискам + +Результат: + собака — це ссавець + кішка — це ссавець + миша — це ссавець +""" +for animal in ["собака", "кішка", "миша"]: + # Можете використовувати оператор {0} для інтерполяції форматованих рядків + print "{0} — це ссавець".format(animal) + +""" +"range(число)" повертає список чисел +від нуля до заданого числа +Друкує: + 0 + 1 + 2 + 3 +""" +for i in range(4): + print(i) +""" +"range(нижня_границя, верхня_границя)" повертає список чисел +від нижньої границі до верхньої +Друкує: + 4 + 5 + 6 + 7 +""" +for i in range(4, 8): + print i + +""" +Цикли while продовжуються до тих пір, поки вказана умова не стане хибною. +Друкує: + 0 + 1 + 2 + 3 +""" +x = 0 +while x < 4: + print(x) + x += 1 # Короткий запис для x = x + 1 + +# Обробляйте винятки блоками try/except + +# Працює у Python 2.6 і вище: +try: + # Аби створити виняток, використовується raise + raise IndexError("Помилка у індексі!") +except IndexError as e: + pass # pass — оператор, який нічого не робить. Зазвичай тут відбувається + # відновлення після помилки. +except (TypeError, NameError): + pass # Винятки можна обробляти групами, якщо потрібно. +else: # Необов'язковий вираз. Має слідувати за останнім блоком except + print("Все добре!") # Виконається лише якщо не було ніяких винятків +finally: # Виконується у будь-якому випадку + print "Тут ми можемо звільнити ресурси" + +# Замість try/finally для звільнення ресурсів +# ви можете використовувати вираз with +with open("myfile.txt") as f: + for line in f: + print line + + +#################################################### +## 4. Функції +#################################################### + +# Використовуйте def для створення нових функцій +def add(x, y): + print "x дорівнює {0}, а y дорівнює {1}".format(x, y) + return x + y # Повертайте результат за допомогою ключового слова return + + +# Виклик функції з аргументами +add(5, 6) # => друкує «x дорівнює 5, а y дорівнює 6» і повертає 11 + +# Інший спосіб виклику функції — виклик з іменованими аргументами +add(y=6, x=5) # Іменовані аргументи можна вказувати у будь-якому порядку + + +# Ви можете визначити функцію, яка приймає змінну кількість аргументів, +# які будуть інтерпретовані як кортеж, за допомогою * +def varargs(*args): + return args + + +varargs(1, 2, 3) # => (1,2,3) + + +# А також можете визначити функцію, яка приймає змінне число +# іменованих аргументів, котрі будуть інтерпретовані як словник, за допомогою ** +def keyword_args(**kwargs): + return kwargs + + +# Давайте подивимось що з цього вийде +keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"} + +# Якщо хочете, можете використовувати обидва способи одночасно +def all_the_args(*args, **kwargs): + print(args) + print(kwargs) + + +""" +all_the_args(1, 2, a=3, b=4) друкує: + (1, 2) + {"a": 3, "b": 4} +""" + +# Коли викликаєте функції, то можете зробити навпаки! +# Використовуйте символ * аби розпакувати позиційні аргументи і +# ** для іменованих аргументів +args = (1, 2, 3, 4) +kwargs = {"a": 3, "b": 4} +all_the_args(*args) # еквівалентно foo(1, 2, 3, 4) +all_the_args(**kwargs) # еквівалентно foo(a=3, b=4) +all_the_args(*args, **kwargs) # еквівалентно foo(1, 2, 3, 4, a=3, b=4) + +# ви можете передавати довільне число позиційних або іменованих аргументів +# іншим функціям, які їх приймають, розпаковуючи за допомогою +# * або ** відповідно +def pass_all_the_args(*args, **kwargs): + all_the_args(*args, **kwargs) + print varargs(*args) + print keyword_args(**kwargs) + + +# Область визначення функцій +x = 5 + + +def set_x(num): + # Локальна змінна x - не те ж саме, що глобальна змінна x + x = num # => 43 + print x # => 43 + + +def set_global_x(num): + global x + print x # => 5 + x = num # глобальна змінна x тепер дорівнює 6 + print x # => 6 + + +set_x(43) +set_global_x(6) + +# В Python функції є об'єктами першого класу +def create_adder(x): + def adder(y): + return x + y + + return adder + + +add_10 = create_adder(10) +add_10(3) # => 13 + +# Також є і анонімні функції +(lambda x: x > 2)(3) # => True +(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5 + +# Присутні вбудовані функції вищого порядку +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] + +# Для зручного відображення і фільтрації можна використовувати +# включення у вигляді списків +[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] + +# Ви також можете скористатися включеннями множин та словників +{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. Класи +#################################################### + +# Аби отримати клас, ми наслідуємо object. +class Human(object): + # Атрибут класу. Він розділяється всіма екземплярами цього класу. + species = "H. sapiens" + + # Звичайний конструктор, буде викликаний при ініціалізації екземпляру класу + # Зверніть увагу, що подвійне підкреслення на початку та наприкінці імені + # використовується для позначення об'єктів та атрибутів, + # які використовуються Python, але знаходяться у просторах імен, + # якими керує користувач. Не варто вигадувати для них імена самостійно. + def __init__(self, name): + # Присвоєння значення аргумента атрибуту класу name + self.name = name + + # Ініціалізуємо властивість + self.age = 0 + + # Метод екземпляру. Всі методи приймають self у якості першого аргументу + def say(self, msg): + return "%s: %s" % (self.name, msg) + + # Методи класу розділяються між усіма екземплярами + # Вони викликаються з вказанням викликаючого класу + # у якості першого аргументу + @classmethod + def get_species(cls): + return cls.species + + # Статичний метод викликається без посилання на клас або екземпляр + @staticmethod + def grunt(): + return "*grunt*" + + # Властивість. + # Перетворює метод age() в атрибут тільки для читання + # з таким же ім'ям. + @property + def age(self): + return self._age + + # Це дозволяє змінювати значення властивості + @age.setter + def age(self, age): + self._age = age + + # Це дозволяє видаляти властивість + @age.deleter + def age(self): + del self._age + + +# Створюємо екземпляр класу +i = Human(name="Данило") +print(i.say("привіт")) # Друкує: «Данило: привіт» + +j = Human("Меланка") +print(j.say("Привіт")) # Друкує: «Меланка: привіт» + +# Виклик методу класу +i.get_species() # => "H. sapiens" + +# Зміна розділюваного атрибуту +Human.species = "H. neanderthalensis" +i.get_species() # => "H. neanderthalensis" +j.get_species() # => "H. neanderthalensis" + +# Виклик статичного методу +Human.grunt() # => "*grunt*" + +# Оновлюємо властивість +i.age = 42 + +# Отримуємо значення +i.age # => 42 + +# Видаляємо властивість +del i.age +i.age # => виникає помилка атрибуту + +#################################################### +## 6. Модулі +#################################################### + +# Ви можете імпортувати модулі +import math + +print(math.sqrt(16)) # => 4 + +# Ви можете імпортувати окремі функції з модуля +from math import ceil, floor + +print(ceil(3.7)) # => 4.0 +print(floor(3.7)) # => 3.0 + +# Можете імпортувати всі функції модуля. +# Попередження: краще так не робіть +from math import * + +# Можете скорочувати імена модулів +import math as m + +math.sqrt(16) == m.sqrt(16) # => True +# Ви також можете переконатися, що функції еквівалентні +from math import sqrt + +math.sqrt == m.sqrt == sqrt # => True + +# Модулі в Python — це звичайні Python-файли. Ви +# можете писати свої модулі та імпортувати їх. Назва +# модуля співпадає з назвою файлу. + +# Ви можете дізнатися, які функції та атрибути визначені +# в модулі +import math + +dir(math) + + +# Якщо у вас є Python скрипт з назвою math.py у тій же папці, що +# і ваш поточний скрипт, то файл math.py +# може бути завантажено замість вбудованого у Python модуля. +# Так трапляється, оскільки локальна папка має перевагу +# над вбудованими у Python бібліотеками. + +#################################################### +## 7. Додатково +#################################################### + +# Генератори +# Генератор "генерує" значення тоді, коли вони запитуються, замість того, +# щоб зберігати все одразу + +# Метод нижче (*НЕ* генератор) подвоює всі значення і зберігає їх +# в `double_arr`. При великих розмірах може знадобитися багато ресурсів! +def double_numbers(iterable): + double_arr = [] + for i in iterable: + double_arr.append(i + i) + return double_arr + + +# Тут ми спочатку подвоюємо всі значення, потім повертаємо їх, +# аби перевірити умову +for value in double_numbers(range(1000000)): # `test_non_generator` + print value + if value > 5: + break + + +# Натомість ми можемо скористатися генератором, аби "згенерувати" +# подвійне значення, як тільки воно буде запитане +def double_numbers_generator(iterable): + for i in iterable: + yield i + i + + +# Той самий код, але вже з генератором, тепер дозволяє нам пройтися по +# значенням і подвоювати їх одне за одним якраз тоді, коли вони обробляються +# за нашою логікою, одне за одним. А як тільки ми бачимо, що value > 5, ми +# виходимо з циклу і більше не подвоюємо більшість значень, +# які отримали на вхід (НАБАГАТО ШВИДШЕ!) +for value in double_numbers_generator(xrange(1000000)): # `test_generator` + print value + if value > 5: + break + +# Між іншим: ви помітили використання `range` у `test_non_generator` і +# `xrange` у `test_generator`? +# Як `double_numbers_generator` є версією-генератором `double_numbers`, так +# і `xrange` є аналогом `range`, але у вигляді генератора. +# `range` поверне нам масив з 1000000 значень +# `xrange`, у свою чергу, згенерує 1000000 значень для нас тоді, +# коли ми їх запитуємо / будемо проходитись по ним. + +# Аналогічно включенням у вигляді списків, ви можете створювати включення +# у вигляді генераторів. +values = (-x for x in [1, 2, 3, 4, 5]) +for x in values: + print(x) # друкує -1 -2 -3 -4 -5 + +# Включення у вигляді генератора можна явно перетворити у список +values = (-x for x in [1, 2, 3, 4, 5]) +gen_to_list = list(values) +print(gen_to_list) # => [-1, -2, -3, -4, -5] + +# Декоратори +# Декоратор – це функція вищого порядку, яка приймає та повертає функцію. +# Простий приклад використання – декоратор add_apples додає елемент 'Apple' в +# список fruits, який повертає цільова функція get_fruits. +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'] + +# Друкуємо список разом з елементом 'Apple', який знаходиться в ньому: +# Banana, Mango, Orange, Apple +print ', '.join(get_fruits()) + +# У цьому прикладі beg обертає say +# Beg викличе say. Якщо say_please дорівнюватиме True, то повідомлення, +# що повертається, буде змінено. +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, "Будь ласка! Я бідний :(") + return msg + + return wrapper + + +@beg +def say(say_please=False): + msg = "Ви можете купити мені пива?" + return msg, say_please + + +print say() # Ви можете купити мені пива? +print say(say_please=True) # Ви можете купити мені пива? Будь ласка! Я бідний :( +``` + +## Готові до більшого? + +### Безкоштовні онлайн-матеріали + +* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/) +* [Dive Into Python](http://www.diveintopython.net/) +* [Официальная документация](http://docs.python.org/2.6/) +* [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) + +### Платні + +* [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/visualbasic.html.markdown b/visualbasic.html.markdown index 041641d3..63f224b7 100644 --- a/visualbasic.html.markdown +++ b/visualbasic.html.markdown @@ -5,7 +5,7 @@ contributors: filename: learnvisualbasic.vb --- -```vbnet +``` Module Module1 Sub Main() diff --git a/zh-cn/c-cn.html.markdown b/zh-cn/c-cn.html.markdown index 1e10416e..02ec7f7b 100644 --- a/zh-cn/c-cn.html.markdown +++ b/zh-cn/c-cn.html.markdown @@ -41,7 +41,7 @@ enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT}; void function_1(char c); void function_2(void); -// 如果函数出现在main()之后,那么必须在main()之前 +// 如果函数调用在main()之后,那么必须在main()之前 // 先声明一个函数原型 int add_two_ints(int x1, int x2); // 函数原型 diff --git a/zh-cn/fortran95-cn.html.markdown b/zh-cn/fortran95-cn.html.markdown new file mode 100644 index 00000000..e28d309f --- /dev/null +++ b/zh-cn/fortran95-cn.html.markdown @@ -0,0 +1,435 @@ +--- +language: Fortran +filename: learnfortran-cn.f95 +contributors: + - ["Robert Steed", "https://github.com/robochat"] +translators: + - ["Corvusnest", "https://github.com/Corvusnest"] +lang: zh-cn +--- + +Fortran 是最古老的计算机语言之一。它由IBM开发于1950年用于数值运算(Fortran 为 "Formula +Translation" 的缩写)。虽然该语言已年代久远,但目前仍用于高性能计算,如天气预报。 +该语言仍在持续发展,并且基本保持向下兼容。知名的版本为 Fortran 77, Fortran 90, +Fortran 95, Fortran 2003, Fortran 2008 与 Fortran 2015。 + +这篇概要将讨论 Fortran 95 的一些特征。因为它是目前所广泛采用的标准版本,并且与最新版本的内容 +也基本相同(而 Fortran 77 则是一个非常不同的版本)。 + +```fortran + +! 这是一行注释 + + +program example !声明一个叫做 example 的程序 + + ! 代码只能放在程序、函数、子程序或者模块内部 + ! 推荐使用缩进,但不是必须的。 + + ! 声明变量 + ! =================== + + ! 所有的声明必须放在语句与表达式之前 + + implicit none !阻止变量的隐式声明 (推荐!) + ! Implicit none 必须在每一个 函数/程序/模块 中进行声明 + + ! 重要 - Fortran 对大小写不敏感 + real z + REAL Z2 + + real :: v,x ! 警告: 默认值取决于编译器! + real :: a = 3, b=2E12, c = 0.01 + integer :: i, j, k=1, m + real, parameter :: PI = 3.1415926535897931 !声明一个常量 + logical :: y = .TRUE. , n = .FALSE. !布尔值 + complex :: w = (0,1) !sqrt(-1) (译注: 定义复数,此为-1的平方根) + character (len=3) :: month !长度为3的字符串 + + real :: array(6) !声明长度为6的浮点数数组 + real, dimension(4) :: arrayb !声明数组的另一种方法 + integer :: arrayc(-10:10) !有着自定义索引的数组 + real :: array2d(3,2) !多维数组 + + ! 分隔符 '::' 并不总是必要的,但推荐使用 + + ! 还存在很多其他的变量特征: + real, pointer :: p !声明一个指针 + + integer, parameter :: LP = selected_real_kind(20) + real (kind = LP) :: d !长精度变量 + + ! 警告:在声明期间初始化变量将导致在函数内发生问题,因为这将自动具备了 “save” 属性, + ! 因此变量的值在函数的多次调用期间将被存储。一般来说,除了常量,应分开声明与初始化! + + ! 字符串 + ! ======= + + character :: a_char = 'i' + character (len = 6) :: a_str = "qwerty" + character (len = 30) :: str_b + character (len = *), parameter :: a_long_str = "This is a long string." + !可以通过使用 (len=*) 来自动判断长度,但只对常量有效 + + str_b = a_str // " keyboard" !通过 // 操作符来连接字符串 + + + ! 任务与计算 + ! ======================= + + Z = 1 !向之前声明的变量 z 赋值 (大小写不敏感). + j = 10 + 2 - 3 + a = 11.54 / (2.3 * 3.1) + b = 2**3 !幂 + + + ! 控制流程语句 与 操作符 + ! =================================== + + !单行 if 语句 + if (z == a) b = 4 !判别句永远需要放在圆括号内 + + if (z /= a) then !z 不等于 a + ! 其他的比较运算符: < > <= >= == /= + b = 4 + else if (z .GT. a) then !z 大于(Greater) a + ! 文本形式的比较运算符: .LT. .GT. .LE. .GE. .EQ. .NE. + b = 6 + else if (z < a) then !'then' 必须放在该行 + b = 5 !执行部分必须放在新的一行里 + else + b = 10 + end if !结束语句需要 'if' (也可以用 'endif'). + + + if (.NOT. (x < c .AND. v >= a .OR. z == z)) then !布尔操作符 + inner: if (.TRUE.) then !可以为 if 结构命名 + b = 1 + endif inner !接下来必须命名 endif 语句. + endif + + + i = 20 + select case (i) + case (0) !当 i == 0 + j=0 + case (1:10) !当 i 为 1 到 10 之内 ( 1 <= i <= 10 ) + j=1 + case (11:) !当 i>=11 + j=2 + case default + j=3 + end select + + + month = 'jan' + ! 状态值可以为整数、布尔值或者字符类型 + ! Select 结构同样可以被命名 + monthly: select case (month) + case ("jan") + j = 0 + case default + j = -1 + end select monthly + + do i=2,10,2 !从2到10(包含2和10)以2为步进值循环 + innerloop: do j=1,3 !循环同样可以被命名 + exit !跳出循环 + end do innerloop + cycle !重复跳入下一次循环 + enddo + + + ! Goto 语句是存在的,但强烈不建议使用 + goto 10 + stop 1 !立即停止程序 (返回一个设定的状态码). +10 j = 201 !这一行被标注为 10 行 (line 10) + + + ! 数组 + ! ====== + array = (/1,2,3,4,5,6/) + array = [1,2,3,4,5,6] !当使用 Fortran 2003 版本. + arrayb = [10.2,3e3,0.41,4e-5] + array2d = reshape([1.0,2.0,3.0,4.0,5.0,6.0], [3,2]) + + ! Fortran 数组索引起始于 1 + ! (默认下如此,也可以为数组定义不同的索引起始) + v = array(1) !获取数组的第一个元素 + v = array2d(2,2) + + print *, array(3:5) !打印从第3到第五5之内的所有元素 + print *, array2d(1,:) !打印2维数组的第一列 + + array = array*3 + 2 !可为数组设置数学表达式 + array = array*array !数组操作支持元素级(操作) (element-wise) + !array = array*array2d !这两类数组并不是同一个维度的 + + ! 有很多内置的数组操作函数 + c = dot_product(array,array) !点乘 (点积) + ! 用 matmul() 来进行矩阵运算. + c = sum(array) + c = maxval(array) + print *, minloc(array) + c = size(array) + print *, shape(array) + m = count(array > 0) + + ! 遍历一个数组 (一般使用 Product() 函数). + v = 1 + do i = 1, size(array) + v = v*array(i) + end do + + ! 有条件地执行元素级操作 + array = [1,2,3,4,5,6] + where (array > 3) + array = array + 1 + elsewhere (array == 2) + array = 1 + elsewhere + array = 0 + end where + + ! 隐式DO循环可以很方便地创建数组 + array = [ (i, i = 1,6) ] !创建数组 [1,2,3,4,5,6] + array = [ (i, i = 1,12,2) ] !创建数组 [1,3,5,7,9,11] + array = [ (i**2, i = 1,6) ] !创建数组 [1,4,9,16,25,36] + array = [ (4,5, i = 1,3) ] !创建数组 [4,5,4,5,4,5] + + + ! 输入/输出 + ! ============ + + print *, b !向命令行打印变量 'b' + + ! 我们可以格式化输出 + print "(I6)", 320 !打印 ' 320' + print "(I6.4)", 3 !打印 ' 0003' + print "(F6.3)", 4.32 !打印 ' 4.320' + + + ! 该字母与数值规定了给定的数值与字符所用于打印输出的类型与格式 + ! 字母可为 I (整数), F (浮点数), E (工程格式), + ! L (逻辑/布尔值), A (字符) ... + print "(I3)", 3200 !如果数值无法符合格式将打印 '***' + + ! 可以同时设定多种格式 + print "(I5,F6.2,E6.2)", 120, 43.41, 43.41 + print "(3I5)", 10, 20, 30 !连续打印3个整数 (字段宽度 = 5). + print "(2(I5,F6.2))", 120, 43.42, 340, 65.3 !连续分组格式 + + ! 我们也可以从终端读取输入 + read *, v + read "(2F6.2)", v, x !读取2个数值 + + ! 读取文件 + open(unit=11, file="records.txt", status="old") + ! 文件被引用带有一个单位数 'unit', 为一个取值范围在9-99的整数 + ! 'status' 可以为 {'old','replace','new'} 其中之一 + read(unit=11, fmt="(3F10.2)") a, b, c + close(11) + + ! 写入一个文件 + open(unit=12, file="records.txt", status="replace") + write(12, "(F10.2,F10.2,F10.2)") c, b, a + close(12) + ! 在讨论范围之外的还有更多的细节与可用功能,并于老版本的 Fortran 保持兼容 + + + ! 内置函数 + ! ================== + + ! Fortran 拥有大约 200 个内置函数/子程序 + ! 例子 + call cpu_time(v) !以秒为单位设置时间 + k = ior(i,j) !2个整数的位或运算 + v = log10(x) !以10为底的log运算 + i = floor(b) !返回一个最接近的整数小于或等于x (地板数) + v = aimag(w) !复数的虚数部分 + + + ! 函数与子程序 + ! ======================= + + ! 一个子程序会根据输入值运行一些代码并会导致副作用 (side-effects) 或修改输入值 + ! (译者注: 副作用是指对子程序/函数外的环境产生影响,如修改变量) + + call routine(a,c,v) !调用子程序 + + ! 一个函数会根据输入的一系列数值来返回一个单独的值 + ! 但输入值仍然可能被修改以及产生副作用 + + m = func(3,2,k) !调用函数 + + ! 函数可以在表达式内被调用 + Print *, func2(3,2,k) + + ! 一个纯函数不会去修改输入值或产生副作用 + m = func3(3,2,k) + + +contains ! 用于定义程序内部的副程序(sub-programs)的区域 + + ! Fortran 拥有一些不同的方法去定义函数 + + integer function func(a,b,c) !一个返回一个整数的函数 + implicit none !最好也在函数内将含蓄模式关闭 (implicit none) + integer :: a,b,c !输入值类型定义在函数内部 + if (a >= 2) then + func = a + b + c !返回值默认为函数名 + return !可以在函数内任意时间返回当前值 + endif + func = a + c + ! 在函数的结尾不需要返回语句 + end function func + + + function func2(a,b,c) result(f) !将返回值声明为 'f' + implicit none + integer, intent(in) :: a,b !可以声明让变量无法被函数修改 + integer, intent(inout) :: c + integer :: f !函数的返回值类型在函数内声明 + integer :: cnt = 0 !注意 - 隐式的初始化变量将在函数的多次调用间被存储 + f = a + b - c + c = 4 !变动一个输入变量的值 + cnt = cnt + 1 !记录函数的被调用次数 + end function func2 + + + pure function func3(a,b,c) !一个没有副作用的纯函数 + implicit none + integer, intent(in) :: a,b,c + integer :: func3 + func3 = a*b*c + end function func3 + + + subroutine routine(d,e,f) + implicit none + real, intent(inout) :: f + real, intent(in) :: d,e + f = 2*d + 3*e + f + end subroutine routine + + +end program example ! 函数定义完毕 ----------------------- + +! 函数与子程序的外部声明对于生成程序清单来说,需要一个接口声明(即使它们在同一个源文件内)(见下) +! 使用 'contains' 可以很容易地在模块或程序内定义它们 + +elemental real function func4(a) result(res) +! 一个元函数(elemental function) 为一个纯函数使用一个标量输入值 +! 但同时也可以用在一个数组并对其中的元素分别处理,之后返回一个新的数组 + real, intent(in) :: a + res = a**2 + 1.0 +end function func4 + + +! 模块 +! ======= + +! 模块十分适合于存放与复用相关联的一组声明、函数与子程序 + +module fruit + real :: apple + real :: pear + real :: orange +end module fruit + + +module fruity + + ! 声明必须按照顺序: 模块、接口、变量 + ! (同样可在程序内声明模块和接口) + + use fruit, only: apple, pear ! 使用来自于 fruit 模块的 apple 和 pear + implicit none !在模块导入后声明 + + private !使得模块内容为私有(private)(默认为公共 public) + ! 显式声明一些变量/函数为公共 + public :: apple,mycar,create_mycar + ! 声明一些变量/函数为私有(在当前情况下没必要)(译注: 因为前面声明了模块全局 private) + private :: func4 + + ! 接口 + ! ========== + ! 在模块内显式声明一个外部函数/程序 + ! 一般最好将函数/程序放进 'contains' 部分内 + interface + elemental real function func4(a) result(res) + real, intent(in) :: a + end function func4 + end interface + + ! 重载函数可以通过已命名的接口来定义 + interface myabs + ! 可以通过使用 'module procedure' 关键词来包含一个已在模块内定义的函数 + module procedure real_abs, complex_abs + end interface + + ! 派生数据类型 + ! ================== + ! 可创建自定义数据结构 + type car + character (len=100) :: model + real :: weight !(公斤 kg) + real :: dimensions(3) !例: 长宽高(米) + character :: colour + end type car + + type(car) :: mycar !声明一个自定义类型的变量 + ! 用法具体查看 create_mycar() + + ! 注: 模块内没有可执行的语句 + +contains + + subroutine create_mycar(mycar) + ! 展示派生数据类型的使用 + implicit none + type(car),intent(out) :: mycar + + ! 通过 '%' 操作符来访问(派生数据)类型的元素 + mycar%model = "Ford Prefect" + mycar%colour = 'r' + mycar%weight = 1400 + mycar%dimensions(1) = 5.0 !索引默认起始值为 1 ! + mycar%dimensions(2) = 3.0 + mycar%dimensions(3) = 1.5 + + end subroutine + + real function real_abs(x) + real :: x + if (x<0) then + real_abs = -x + else + real_abs = x + end if + end function real_abs + + real function complex_abs(z) + complex :: z + ! 过长的一行代码可通过延续符 '&' 来换行 + complex_abs = sqrt(real(z)**2 + & + aimag(z)**2) + end function complex_abs + + +end module fruity + +``` + +### 更多资源 + +了解更多的 Fortran 信息: + ++ [wikipedia](https://en.wikipedia.org/wiki/Fortran) ++ [Fortran_95_language_features](https://en.wikipedia.org/wiki/Fortran_95_language_features) ++ [fortranwiki.org](http://fortranwiki.org) ++ [www.fortran90.org/](http://www.fortran90.org) ++ [list of Fortran 95 tutorials](http://www.dmoz.org/Computers/Programming/Languages/Fortran/FAQs%2C_Help%2C_and_Tutorials/Fortran_90_and_95/) ++ [Fortran wikibook](https://en.wikibooks.org/wiki/Fortran) ++ [Fortran resources](http://www.fortranplus.co.uk/resources/fortran_resources.pdf) ++ [Mistakes in Fortran 90 Programs That Might Surprise You](http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html) diff --git a/zh-cn/visualbasic-cn.html.markdown b/zh-cn/visualbasic-cn.html.markdown index cdc2d808..e30041b3 100644 --- a/zh-cn/visualbasic-cn.html.markdown +++ b/zh-cn/visualbasic-cn.html.markdown @@ -8,7 +8,7 @@ lang: zh-cn filename: learnvisualbasic-cn.vb --- -```vbnet +``` Module Module1 Sub Main() |