diff options
33 files changed, 2765 insertions, 853 deletions
diff --git a/awk.html.markdown b/awk.html.markdown index de26c0a1..3d2c4ccb 100644 --- a/awk.html.markdown +++ b/awk.html.markdown @@ -6,14 +6,15 @@ contributors: --- -AWK is a standard tool on every POSIX-compliant UNIX system. It's like a -stripped-down Perl, perfect for text-processing tasks and other scripting -needs. It has a C-like syntax, but without semicolons, manual memory -management, or static typing. It excels at text processing. You can call to it -from a shell script, or you can use it as a stand-alone scripting language. - -Why use AWK instead of Perl? Mostly because AWK is part of UNIX. You can always -count on it, whereas Perl's future is in question. AWK is also easier to read +AWK is a standard tool on every POSIX-compliant UNIX system. It's like +flex/lex, from the command-line, perfect for text-processing tasks and +other scripting needs. It has a C-like syntax, but without mandatory +semicolons (although, you should use them anyway, because they are required +when you're writing one-liners, something AWK excells at), manual memory +management, or static typing. It excels at text processing. You can call to +it from a shell script, or you can use it as a stand-alone scripting language. + +Why use AWK instead of Perl? Readability. AWK is easier to read than Perl. For simple text-processing scripts, particularly ones that read files line by line and split on delimiters, AWK is probably the right tool for the job. @@ -23,8 +24,23 @@ the job. # Comments are like this -# AWK programs consist of a collection of patterns and actions. The most -# important pattern is called BEGIN. Actions go into brace blocks. + +# AWK programs consist of a collection of patterns and actions. +pattern1 { action; } # just like lex +pattern2 { action; } + +# There is an implied loop and AWK automatically reads and parses each +# record of each file supplied. Each record is split by the FS delimiter, +# which defaults to white-space (multiple spaces,tabs count as one) +# You cann assign FS either on the command line (-F C) or in your BEGIN +# pattern + +# One of the special patterns is BEGIN. The BEGIN pattern is true +# BEFORE any of the files are read. The END pattern is true after +# an End-of-file from the last file (or standard-in if no files specified) +# There is also an output field separator (OFS) that you can assign, which +# defaults to a single space + BEGIN { # BEGIN will run at the beginning of the program. It's where you put all @@ -32,114 +48,116 @@ BEGIN { # have no text files, then think of BEGIN as the main entry point. # Variables are global. Just set them or use them, no need to declare.. - count = 0 + count = 0; # Operators just like in C and friends - a = count + 1 - b = count - 1 - c = count * 1 - d = count / 1 # integer division - e = count % 1 # modulus - f = count ^ 1 # exponentiation - - a += 1 - b -= 1 - c *= 1 - d /= 1 - e %= 1 - f ^= 1 + a = count + 1; + b = count - 1; + c = count * 1; + d = count / 1; # integer division + e = count % 1; # modulus + f = count ^ 1; # exponentiation + + a += 1; + b -= 1; + c *= 1; + d /= 1; + e %= 1; + f ^= 1; # Incrementing and decrementing by one - a++ - b-- + a++; + b--; # As a prefix operator, it returns the incremented value - ++a - --b + ++a; + --b; # Notice, also, no punctuation such as semicolons to terminate statements # Control statements if (count == 0) - print "Starting with count of 0" + print "Starting with count of 0"; else - print "Huh?" + print "Huh?"; # Or you could use the ternary operator - print (count == 0) ? "Starting with count of 0" : "Huh?" + print (count == 0) ? "Starting with count of 0" : "Huh?"; # Blocks consisting of multiple lines use braces while (a < 10) { print "String concatenation is done" " with a series" " of" - " space-separated strings" - print a + " space-separated strings"; + print a; - a++ + a++; } for (i = 0; i < 10; i++) - print "Good ol' for loop" + print "Good ol' for loop"; # As for comparisons, they're the standards: - a < b # Less than - a <= b # Less than or equal - a != b # Not equal - a == b # Equal - a > b # Greater than - a >= b # Greater than or equal + # a < b # Less than + # a <= b # Less than or equal + # a != b # Not equal + # a == b # Equal + # a > b # Greater than + # a >= b # Greater than or equal # Logical operators as well - a && b # AND - a || b # OR + # a && b # AND + # a || b # OR # In addition, there's the super useful regular expression match if ("foo" ~ "^fo+$") - print "Fooey!" + print "Fooey!"; if ("boo" !~ "^fo+$") - print "Boo!" + print "Boo!"; # Arrays - arr[0] = "foo" - arr[1] = "bar" - # Unfortunately, there is no other way to initialize an array. Ya just - # gotta chug through every value line by line like that. - - # You also have associative arrays - assoc["foo"] = "bar" - assoc["bar"] = "baz" + arr[0] = "foo"; + arr[1] = "bar"; + + # You can also initialize an array with the built-in function split() + + n = split("foo:bar:baz", arr, ":"); + + # You also have associative arrays (actually, they're all associative arrays) + assoc["foo"] = "bar"; + assoc["bar"] = "baz"; # And multi-dimensional arrays, with some limitations I won't mention here - multidim[0,0] = "foo" - multidim[0,1] = "bar" - multidim[1,0] = "baz" - multidim[1,1] = "boo" + multidim[0,0] = "foo"; + multidim[0,1] = "bar"; + multidim[1,0] = "baz"; + multidim[1,1] = "boo"; # You can test for array membership if ("foo" in assoc) - print "Fooey!" + print "Fooey!"; # You can also use the 'in' operator to traverse the keys of an array for (key in assoc) - print assoc[key] + print assoc[key]; # The command line is in a special array called ARGV for (argnum in ARGV) - print ARGV[argnum] + print ARGV[argnum]; # You can remove elements of an array # This is particularly useful to prevent AWK from assuming the arguments # are files for it to process - delete ARGV[1] + delete ARGV[1]; # The number of command line arguments is in a variable called ARGC - print ARGC + print ARGC; # AWK has several built-in functions. They fall into three categories. I'll # demonstrate each of them in their own functions, defined later. - return_value = arithmetic_functions(a, b, c) - string_functions() - io_functions() + return_value = arithmetic_functions(a, b, c); + string_functions(); + io_functions(); } # Here's how you define a function @@ -159,26 +177,26 @@ function arithmetic_functions(a, b, c, d) { # Now, to demonstrate the arithmetic functions # Most AWK implementations have some standard trig functions - localvar = sin(a) - localvar = cos(a) - localvar = atan2(b, a) # arc tangent of b / a + localvar = sin(a); + localvar = cos(a); + localvar = atan2(b, a); # arc tangent of b / a # And logarithmic stuff - localvar = exp(a) - localvar = log(a) + localvar = exp(a); + localvar = log(a); # Square root - localvar = sqrt(a) + localvar = sqrt(a); # Truncate floating point to integer - localvar = int(5.34) # localvar => 5 + localvar = int(5.34); # localvar => 5 # Random numbers - srand() # Supply a seed as an argument. By default, it uses the time of day - localvar = rand() # Random number between 0 and 1. + srand(); # Supply a seed as an argument. By default, it uses the time of day + localvar = rand(); # Random number between 0 and 1. # Here's how to return a value - return localvar + return localvar; } function string_functions( localvar, arr) { @@ -188,61 +206,66 @@ function string_functions( localvar, arr) { # Search and replace, first instance (sub) or all instances (gsub) # Both return number of matches replaced - localvar = "fooooobar" - sub("fo+", "Meet me at the ", localvar) # localvar => "Meet me at the bar" - gsub("e+", ".", localvar) # localvar => "m..t m. at th. bar" + localvar = "fooooobar"; + sub("fo+", "Meet me at the ", localvar); # localvar => "Meet me at the bar" + gsub("e+", ".", localvar); # localvar => "m..t m. at th. bar" # Search for a string that matches a regular expression # index() does the same thing, but doesn't allow a regular expression - match(localvar, "t") # => 4, since the 't' is the fourth character + match(localvar, "t"); # => 4, since the 't' is the fourth character # Split on a delimiter - split("foo-bar-baz", arr, "-") # a => ["foo", "bar", "baz"] + n = split("foo-bar-baz", arr, "-"); # a[1] = "foo"; a[2] = "bar"; a[3] = "baz"; n = 3 # Other useful stuff - sprintf("%s %d %d %d", "Testing", 1, 2, 3) # => "Testing 1 2 3" - substr("foobar", 2, 3) # => "oob" - substr("foobar", 4) # => "bar" - length("foo") # => 3 - tolower("FOO") # => "foo" - toupper("foo") # => "FOO" + sprintf("%s %d %d %d", "Testing", 1, 2, 3); # => "Testing 1 2 3" + substr("foobar", 2, 3); # => "oob" + substr("foobar", 4); # => "bar" + length("foo"); # => 3 + tolower("FOO"); # => "foo" + toupper("foo"); # => "FOO" } function io_functions( localvar) { # You've already seen print - print "Hello world" + print "Hello world"; # There's also printf - printf("%s %d %d %d\n", "Testing", 1, 2, 3) + printf("%s %d %d %d\n", "Testing", 1, 2, 3); # AWK doesn't have file handles, per se. It will automatically open a file # handle for you when you use something that needs one. The string you used # for this can be treated as a file handle, for purposes of I/O. This makes - # it feel sort of like shell scripting: + # it feel sort of like shell scripting, but to get the same output, the string + # must match exactly, so use a vaiable: + + outfile = "/tmp/foobar.txt"; - print "foobar" >"/tmp/foobar.txt" + print "foobar" > outfile; - # Now the string "/tmp/foobar.txt" is a file handle. You can close it: - close("/tmp/foobar.txt") + # Now the string outfile is a file handle. You can close it: + close(outfile); # Here's how you run something in the shell - system("echo foobar") # => prints foobar + system("echo foobar"); # => prints foobar # Reads a line from standard input and stores in localvar - getline localvar + getline localvar; - # Reads a line from a pipe - "echo foobar" | getline localvar # localvar => "foobar" - close("echo foobar") + # Reads a line from a pipe (again, use a string so you close it properly) + cmd = "echo foobar"; + cmd | getline localvar; # localvar => "foobar" + close(cmd); # Reads a line from a file and stores in localvar - getline localvar <"/tmp/foobar.txt" - close("/tmp/foobar.txt") + infile = "/tmp/foobar.txt"; + getline localvar < infile; + close(infile); } # As I said at the beginning, AWK programs consist of a collection of patterns -# and actions. You've already seen the all-important BEGIN pattern. Other +# and actions. You've already seen the BEGIN pattern. Other # patterns are used only if you're processing lines from files or standard # input. # @@ -257,7 +280,7 @@ function io_functions( localvar) { # expression, /^fo+bar$/, and will be skipped for any line that fails to # match it. Let's just print the line: - print + print; # Whoa, no argument! That's because print has a default argument: $0. # $0 is the name of the current line being processed. It is created @@ -268,16 +291,16 @@ function io_functions( localvar) { # does. And, like the shell, each field can be access with a dollar sign # This will print the second and fourth fields in the line - print $2, $4 + print $2, $4; # AWK automatically defines many other variables to help you inspect and # process each line. The most important one is NF # Prints the number of fields on this line - print NF + print NF; # Print the last field on this line - print $NF + print $NF; } # Every pattern is actually a true/false test. The regular expression in the @@ -286,7 +309,7 @@ function io_functions( localvar) { # currently processing. Thus, the complete version of it is this: $0 ~ /^fo+bar$/ { - print "Equivalent to the last pattern" + print "Equivalent to the last pattern"; } a > 0 { @@ -315,10 +338,10 @@ a > 0 { BEGIN { # First, ask the user for the name - print "What name would you like the average age for?" + print "What name would you like the average age for?"; # Get a line from standard input, not from files on the command line - getline name <"/dev/stdin" + getline name < "/dev/stdin"; } # Now, match every line whose first field is the given name @@ -335,8 +358,8 @@ $1 == name { # ...etc. There are plenty more, documented in the man page. # Keep track of a running total and how many lines matched - sum += $3 - nlines++ + sum += $3; + nlines++; } # Another special pattern is called END. It will run after processing all the @@ -348,7 +371,7 @@ $1 == name { END { if (nlines) - print "The average age for " name " is " sum / nlines + print "The average age for " name " is " sum / nlines; } ``` @@ -357,3 +380,4 @@ Further Reading: * [Awk tutorial](http://www.grymoire.com/Unix/Awk.html) * [Awk man page](https://linux.die.net/man/1/awk) * [The GNU Awk User's Guide](https://www.gnu.org/software/gawk/manual/gawk.html) GNU Awk is found on most Linux systems. +* [AWK one-liner collection](http://tuxgraphics.org/~guido/scripts/awk-one-liner.html) diff --git a/c.html.markdown b/c.html.markdown index 684d330a..bf93dcf5 100644 --- a/c.html.markdown +++ b/c.html.markdown @@ -9,6 +9,7 @@ contributors: - ["Zachary Ferguson", "https://github.io/zfergus2"] - ["himanshu", "https://github.com/himanshu81494"] - ["Joshua Li", "https://github.com/JoshuaRLi"] + - ["Dragos B. Chirila", "https://github.com/dchirila"] --- Ah, C. Still **the** language of modern high-performance computing. @@ -18,7 +19,7 @@ it more than makes up for it with raw speed. Just be aware of its manual memory management and C will take you as far as you need to go. > **About compiler flags** -> +> > By default, gcc and clang are pretty quiet about compilation warnings and > errors, which can be very useful information. Explicitly using stricter > compiler flags is recommended. Here are some recommended defaults: @@ -89,6 +90,8 @@ int main (int argc, char** argv) // All variables MUST be declared at the top of the current block scope // we declare them dynamically along the code for the sake of the tutorial + // (however, C99-compliant compilers allow declarations near the point where + // the value is used) // ints are usually 4 bytes int x_int = 0; @@ -141,6 +144,17 @@ int main (int argc, char** argv) // You can initialize an array to 0 thusly: char my_array[20] = {0}; + // where the "{0}" part is called an "array initializer". + // NOTE that you get away without explicitly declaring the size of the array, + // IF you initialize the array on the same line. So, the following declaration + // is equivalent: + char my_array[] = {0}; + // BUT, then you have to evaluate the size of the array at run-time, like this: + size_t my_array_size = sizeof(my_array) / sizeof(my_array[0]); + // WARNING If you adopt this approach, you should evaluate the size *before* + // you begin passing the array to function (see later discussion), because + // arrays get "downgraded" to raw pointers when they are passed to functions + // (so the statement above will produce the wrong result inside the function). // Indexing an array is like other languages -- or, // rather, other languages are like C @@ -374,8 +388,8 @@ int main (int argc, char** argv) // respectively, use the CHAR_MAX, SCHAR_MAX and UCHAR_MAX macros from <limits.h> // Integral types can be cast to floating-point types, and vice-versa. - printf("%f\n", (float)100); // %f formats a float - printf("%lf\n", (double)100); // %lf formats a double + printf("%f\n", (double) 100); // %f always formats a double... + printf("%f\n", (float) 100); // ...even with a float. printf("%d\n", (char)100.0); /////////////////////////////////////// @@ -433,7 +447,7 @@ int main (int argc, char** argv) // or when it's the argument of the `sizeof` or `alignof` operator: int arraythethird[10]; int *ptr = arraythethird; // equivalent with int *ptr = &arr[0]; - printf("%zu, %zu\n", sizeof arraythethird, sizeof ptr); + printf("%zu, %zu\n", sizeof(arraythethird), sizeof(ptr)); // probably prints "40, 4" or "40, 8" // Pointers are incremented and decremented based on their type @@ -449,7 +463,7 @@ int main (int argc, char** argv) for (xx = 0; xx < 20; xx++) { *(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx } // Initialize memory to 20, 19, 18, 17... 2, 1 (as ints) - + // Be careful passing user-provided values to malloc! If you want // to be safe, you can use calloc instead (which, unlike malloc, also zeros out the memory) int* my_other_ptr = calloc(20, sizeof(int)); @@ -522,9 +536,11 @@ Example: in-place string reversal void str_reverse(char *str_in) { char tmp; - int ii = 0; + size_t ii = 0; size_t len = strlen(str_in); // `strlen()` is part of the c standard library - for (ii = 0; ii < len / 2; ii++) { + // NOTE: length returned by `strlen` DOESN'T include the + // terminating NULL byte ('\0') + for (ii = 0; ii < len / 2; ii++) { // in C99 you can directly declare type of `ii` here tmp = str_in[ii]; str_in[ii] = str_in[len - ii - 1]; // ii-th char from end str_in[len - ii - 1] = tmp; @@ -703,7 +719,8 @@ typedef void (*my_fnp_type)(char *); "%3.2f"; // minimum 3 digits left and 2 digits right decimal float "%7.4s"; // (can do with strings too) "%c"; // char -"%p"; // pointer +"%p"; // pointer. NOTE: need to (void *)-cast the pointer, before passing + // it as an argument to `printf`. "%x"; // hexadecimal "%o"; // octal "%%"; // prints % diff --git a/css.html.markdown b/css.html.markdown index 3b378d44..64dc097c 100644 --- a/css.html.markdown +++ b/css.html.markdown @@ -135,6 +135,10 @@ selector::after {} .parent * { } /* all descendants */ .parent > * { } /* all children */ +/* Group any number of selectors to define styles that affect all selectors + in the group */ +selector1, selector2 { } + /* #################### ## PROPERTIES #################### */ diff --git a/de-de/bash-de.html.markdown b/de-de/bash-de.html.markdown index 7928b136..7a0db157 100644 --- a/de-de/bash-de.html.markdown +++ b/de-de/bash-de.html.markdown @@ -180,7 +180,7 @@ esac # 'for' Schleifen iterieren über die angegebene Zahl von Argumenten: # Der Inhalt von $Variable wird dreimal ausgedruckt. -for $Variable in {1..3} +for Variable in {1..3} do echo "$Variable" done diff --git a/es-es/learnsmallbasic-es.html.markdown b/es-es/learnsmallbasic-es.html.markdown index 21208792..ff320afb 100644 --- a/es-es/learnsmallbasic-es.html.markdown +++ b/es-es/learnsmallbasic-es.html.markdown @@ -18,7 +18,7 @@ SmallBASIC fue desarrollado originalmente por Nicholas Christopoulos a finales d Versiones de SmallBASIC se han hecho para una serie dispositivos de mano antiguos, incluyendo Franklin eBookman y el Nokia 770. También se han publicado varias versiones de escritorio basadas en una variedad de kits de herramientas GUI, algunas de las cuales han desaparecido. Las plataformas actualmente soportadas son Linux y Windows basadas en SDL2 y Android basadas en NDK. También está disponible una versión de línea de comandos de escritorio, aunque no suele publicarse en formato binario. Alrededor de 2008 una gran corporación lanzó un entorno de programación BASIC con un nombre de similar. SmallBASIC no está relacionado con este otro proyecto. -```SmallBASIC +``` REM Esto es un comentario ' y esto tambien es un comentario diff --git a/fr-fr/dynamic-programming-fr.html.markdown b/fr-fr/dynamic-programming-fr.html.markdown index 24e8c95f..b3660ac9 100644 --- a/fr-fr/dynamic-programming-fr.html.markdown +++ b/fr-fr/dynamic-programming-fr.html.markdown @@ -8,7 +8,6 @@ translators: lang: fr-fr --- - # Programmation dynamique ## Introduction @@ -17,9 +16,9 @@ La programmation dynamique est une technique très efficace pour résoudre une c ## Moyens de résoudre ces problèmes -1.) *De haut en bas* : Commençons à résoudre le problème en le séparant en morceaux. Si nous voyons que le problème a déjà été résolu, alors nous retournons la réponse précédemment sauvegardée. Si le problème n'a pas été résolu, alors nous le résolvons et sauvegardons la réponse. C'est généralement facile et intuitif de réfléchir de cette façon. Cela s'appelle la Mémorisation. +1. *De haut en bas* : Commençons à résoudre le problème en le séparant en morceaux. Si nous voyons que le problème a déjà été résolu, alors nous retournons la réponse précédemment sauvegardée. Si le problème n'a pas été résolu, alors nous le résolvons et sauvegardons la réponse. C'est généralement facile et intuitif de réfléchir de cette façon. Cela s'appelle la Mémorisation. -2.) *De bas en haut* : Il faut analyser le problème et trouver les sous-problèmes, et l'ordre dans lequel il faut les résoudre. Ensuite, nous devons résoudre les sous-problèmes et monter jusqu'au problème que nous voulons résoudre. De cette façon, nous sommes assurés que les sous-problèmes sont résolus avant de résoudre le vrai problème. Cela s'appelle la Programmation Dynamique. +2. *De bas en haut* : Il faut analyser le problème et trouver les sous-problèmes, et l'ordre dans lequel il faut les résoudre. Ensuite, nous devons résoudre les sous-problèmes et monter jusqu'au problème que nous voulons résoudre. De cette façon, nous sommes assurés que les sous-problèmes sont résolus avant de résoudre le vrai problème. Cela s'appelle la Programmation Dynamique. ## Exemple de Programmation Dynamique @@ -27,7 +26,7 @@ Le problème de la plus grande sous-chaîne croissante est de trouver la plus gr Premièrement, nous avons à trouver la valeur de la plus grande sous-chaîne (LSi) à chaque index `i`, avec le dernier élément de la sous-chaîne étant ai. Alors, la plus grande sous-chaîne sera le plus gros LSi. Pour commencer, LSi est égal à 1, car ai est le seul élément de la chaîne (le dernier). Ensuite, pour chaque `j` tel que `j<i` et `aj<ai`, nous trouvons le plus grand LSj et ajoutons le à LSi. L'algorithme fonctionne en temps *O(n2)*. Pseudo-code pour trouver la longueur de la plus grande sous-chaîne croissante : -La complexité de cet algorithme peut être réduite en utilisant une meilleure structure de données qu'un tableau. Par exemple, si nous sauvegardions le tableau d'origine, ou une variable comme plus_grande_chaîne_jusqu'à_maintenant et son index, nous pourrions sauver beaucoup de temps. +La complexité de cet algorithme peut être réduite en utilisant une meilleure structure de données qu'un tableau. Par exemple, si nous sauvegardions le tableau d'origine, ou une variable comme `plus_grande_chaîne_jusqu'à_maintenant` et son index, nous pourrions sauver beaucoup de temps. Le même concept peut être appliqué pour trouver le chemin le plus long dans un graphe acyclique orienté. @@ -43,12 +42,9 @@ Le même concept peut être appliqué pour trouver le chemin le plus long dans u ### Problèmes classiques de programmation dynamique -L'algorithme de Floyd Warshall(EN)) - Tutorial and C Program source code:http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code - -Problème du sac à dos(EN) - Tutorial and C Program source code: http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem - - -Plus longue sous-chaîne commune(EN) - Tutorial and C Program source code : http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence +- L'algorithme de Floyd Warshall(EN)) - Tutorial and C Program source code:http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code +- Problème du sac à dos(EN) - Tutorial and C Program source code: http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem +- Plus longue sous-chaîne commune(EN) - Tutorial and C Program source code : http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence ## Online Resources diff --git a/fr-fr/lambda-calculus-fr.html.markdown b/fr-fr/lambda-calculus-fr.html.markdown new file mode 100644 index 00000000..68868830 --- /dev/null +++ b/fr-fr/lambda-calculus-fr.html.markdown @@ -0,0 +1,105 @@ +--- +category: Algorithms & Data Structures +name: Lambda Calculus +contributors: + - ["Max Sun", "http://github.com/maxsun"] +translators: + - ["Yvan Sraka", "https://github.com/yvan-sraka"] +--- + +# Lambda-calcul + +Le Lambda-calcul (λ-calcul), créé à l'origine par [Alonzo Church](https://en.wikipedia.org/wiki/Alonzo_Church), est le plus petit langage de programmation au monde. En dépit de ne pas avoir de nombres, de chaînes, de booléens, ou de tout type de données sans fonction, le lambda calcul peut être utilisé pour représenter n'importe quelle machine de Turing! + +Le Lambda-calcul est composé de 3 éléments : **variables**, **fonctions** et **applications**. + + +| Nom | Syntaxe | Exemple | Explication | +|-------------|------------------------------------|-----------|---------------------------------------------------| +| Variable | `<nom>` | `x` | une variable nommée "x" | +| Fonction | `λ<paramètres>.<corps>` | `λx.x` | une fonction avec le paramètre "x" et le corps "x"| +| Application | `<fonction><variable ou function>` | `(λx.x)a` | appel de la fonction "λx.x" avec l'argument "a" | + +La fonction la plus fondamentale est la fonction identité: `λx.x` qui est équivalente à `f(x) = x`. Le premier "x" est l'argument de la fonction, et le second est le corps de la fonction. + +## Variables libres et liées : + +- Dans la fonction `λx.x`, "x" s'appelle une variable liée car elle est à la fois dans le corps de la fonction et l'un des paramètres. +- Dans `λx.y`, "y" est appelé une variable libre car elle n'a pas été déclarée plus tôt. + +## Évaluation : + +L'évaluation est réalisée par [β-Réduction](https://en.wikipedia.org/wiki/Lambda_calculus#Beta_reduction), qui est essentiellement une substitution lexicale. + +Lors de l'évaluation de l'expression `(λx.x)a`, nous remplaçons toutes les occurrences de "x" dans le corps de la fonction par "a". + +- `(λx.x)a` vaut après évaluation: `a` +- `(λx.y)a` vaut après évaluation: `y` + +Vous pouvez même créer des fonctions d'ordre supérieur: + +- `(λx.(λy.x))a` vaut après évaluation: `λy.a` + +Bien que le lambda-calcul ne prenne traditionnellement en charge que les fonctions à un seul paramètre, nous pouvons créer des fonctions multi-paramètres en utilisant une technique appelée currying. + +- `(λx.λy.λz.xyz)` est équivalent à `f(x, y, z) = x(y(z))` + +Parfois, `λxy.<corps>` est utilisé de manière interchangeable avec: `λx.λy.<corps>` + +---- + +Il est important de reconnaître que le lambda-calcul traditionnel n'a pas de nombres, de caractères ou tout autre type de données sans fonction! + +## Logique booléenne : + +Il n'y a pas de "Vrai" ou de "Faux" dans le calcul lambda. Il n'y a même pas 1 ou 0. + +Au lieu: + +`T` est représenté par: `λx.λy.x` + +`F` est représenté par: `λx.λy.y` + +Premièrement, nous pouvons définir une fonction "if" `λbtf` qui renvoie `t` si `b` est vrai et `f` si `b` est faux + +`IF` est équivalent à: `λb.λt.λf.b t f` + +En utilisant `IF`, nous pouvons définir les opérateurs logiques de base booléens: + +`a AND b` est équivalent à: `λab.IF a b F` + +`a OR b` est équivalent à: `λab.IF a T b` + +`a NOT b` est équivalent à: `λa.IF a F T` + +*Note: `IF a b c` est equivalent à : `IF(a(b(c)))`* + +## Nombres : + +Bien qu'il n'y ait pas de nombres dans le lambda-calcul, nous pouvons encoder des nombres en utilisant les [nombres de Church](https://en.wikipedia.org/wiki/Church_encoding). + +Pour tout nombre n: <code>n = λf.f<sup>n</sup></code> donc: + +`0 = λf.λx.x` + +`1 = λf.λx.f x` + +`2 = λf.λx.f(f x)` + +`3 = λf.λx.f(f(f x))` + +Pour incrémenter un nombre de Church, nous utilisons la fonction successeur `S(n) = n + 1` qui est: + +`S = λn.λf.λx.f((n f) x)` + +En utilisant `S`, nous pouvons définir la fonction `ADD`: + +`ADD = λab.(a S)n` + +**Défi:** essayez de définir votre propre fonction de multiplication! + +## Pour aller plus loin : + +1. [A Tutorial Introduction to the Lambda Calculus](http://www.inf.fu-berlin.de/lehre/WS03/alpi/lambda.pdf) +2. [Cornell CS 312 Recitation 26: The Lambda Calculus](http://www.cs.cornell.edu/courses/cs3110/2008fa/recitations/rec26.html) +3. [Wikipedia - Lambda Calculus](https://en.wikipedia.org/wiki/Lambda_calculus)
\ No newline at end of file diff --git a/fr-fr/pyqt-fr.html.markdown b/fr-fr/pyqt-fr.html.markdown new file mode 100644 index 00000000..6da9a380 --- /dev/null +++ b/fr-fr/pyqt-fr.html.markdown @@ -0,0 +1,85 @@ +--- +category: tool +tool: PyQT +filename: learnpyqt-fr.py +contributors: + - ["Nathan Hughes", "https://github.com/sirsharpest"] +translators: + - ["DevHugo", "http://twitter.com/devhugo"] +lang: fr-fr +--- + +**Qt** est un framework très connu pour le développement de logiciel cross-platform qui peuvent être lancé sur différents systèmes avec de petit ou aucun changement dans le code, tout en ayant la puissance et la vitesse des applications natives. Bien que **Qt** ait été écrit à l'origine en *C++*. + + +Ceci est une adaptation de l'intro C++ à QT par [Aleksey Kholovchuk](https://github.com/vortexxx192 +), certains exemples du code doivent avoir la même fonctionnalité, +cette version ayant juste été faite en utilisant pyqt! + +```python +import sys +from PyQt4 import QtGui + +def window(): + # Création de l'objet application + app = QtGui.QApplication(sys.argv) + # Création d'un widget où notre label sera placé + w = QtGui.QWidget() + # Ajout d'un label au widget + b = QtGui.QLabel(w) + # Assignation de texte au label + b.setText("Hello World!") + # Assignation des tailles et des informations de placement + w.setGeometry(100, 100, 200, 50) + b.move(50, 20) + # Assignation d'un nom à notre fenêtre + w.setWindowTitle("PyQt") + # Affichage de la fenêtre + w.show() + # Exécution de l'application + sys.exit(app.exec_()) + +if __name__ == '__main__': + window() + +``` + +Pour obtenir certaines des fonctionnalités les plus avancées de **pyqt** nous devons commencer par chercher à construire des éléments supplémentaires. +Ici nous voyons comment introduire une boîte de dialogue popup, utile pour demander une confirmation à un utilisateur ou fournir des informations. + +```Python +import sys +from PyQt4.QtGui import * +from PyQt4.QtCore import * + + +def window(): + app = QApplication(sys.argv) + w = QWidget() + # Creation d'un bouton attaché au widget w + b = QPushButton(w) + b.setText("Press me") + b.move(50, 50) + # Dire à b d'appeler cette fonction quand il est cliqué + # remarquez l'absence de "()" sur l'appel de la fonction + b.clicked.connect(showdialog) + w.setWindowTitle("PyQt Dialog") + w.show() + sys.exit(app.exec_()) + +# Cette fonction devrait créer une fenêtre de dialogue avec un bouton +# qui attend d'être cliqué puis quitte le programme +def showdialog(): + d = QDialog() + b1 = QPushButton("ok", d) + b1.move(50, 50) + d.setWindowTitle("Dialog") + # Cette modalité dit au popup de bloquer le parent pendant qu'il est actif + d.setWindowModality(Qt.ApplicationModal) + # En cliquant je voudrais que tout le processus se termine + b1.clicked.connect(sys.exit) + d.exec_() + +if __name__ == '__main__': + window() +``` diff --git a/haskell.html.markdown b/haskell.html.markdown index 266cf11b..90d47c27 100644 --- a/haskell.html.markdown +++ b/haskell.html.markdown @@ -124,6 +124,9 @@ last [1..5] -- 5 fst ("haskell", 1) -- "haskell" snd ("haskell", 1) -- 1 +-- pair element accessing does not work on n-tuples (i.e. triple, quadruple, etc) +snd ("snd", "can't touch this", "da na na na") -- error! see function below + ---------------------------------------------------- -- 3. Functions ---------------------------------------------------- @@ -159,8 +162,8 @@ fib 1 = 1 fib 2 = 2 fib x = fib (x - 1) + fib (x - 2) --- Pattern matching on tuples: -foo (x, y) = (x + 1, y + 2) +-- Pattern matching on tuples +sndOfTriple (_, y, _) = y -- use a wild card (_) to bypass naming unused value -- Pattern matching on lists. Here `x` is the first element -- in the list, and `xs` is the rest of the list. We can write @@ -203,11 +206,11 @@ foo = (4*) . (10+) foo 5 -- 60 -- fixing precedence --- Haskell has an operator called `$`. This operator applies a function --- to a given parameter. In contrast to standard function application, which --- has highest possible priority of 10 and is left-associative, the `$` operator +-- Haskell has an operator called `$`. This operator applies a function +-- to a given parameter. In contrast to standard function application, which +-- has highest possible priority of 10 and is left-associative, the `$` operator -- has priority of 0 and is right-associative. Such a low priority means that --- the expression on its right is applied as the parameter to the function on its left. +-- the expression on its right is applied as a parameter to the function on its left. -- before even (fib 7) -- false @@ -223,7 +226,7 @@ even . fib $ 7 -- false -- 5. Type signatures ---------------------------------------------------- --- Haskell has a very strong type system, and every valid expression has a type. +-- Haskell has a very strong type system, and every valid expression has a type. -- Some basic types: 5 :: Integer diff --git a/haxe.html.markdown b/haxe.html.markdown index df2a1e78..afb9d1a3 100644 --- a/haxe.html.markdown +++ b/haxe.html.markdown @@ -770,19 +770,18 @@ class UsingExample { ``` We're still only scratching the surface here of what Haxe can do. For a formal -overview of all Haxe features, checkout the [online -manual](http://haxe.org/manual), the [online API](http://api.haxe.org/), and -"haxelib", the [haxe library repo] (http://lib.haxe.org/). +overview of all Haxe features, see the [manual](https://haxe.org/manual) and +the [API docs](https://api.haxe.org/). For a comprehensive directory of available +third-party Haxe libraries, see [Haxelib](https://lib.haxe.org/). For more advanced topics, consider checking out: -* [Abstract types](http://haxe.org/manual/abstracts) -* [Macros](http://haxe.org/manual/macros), and [Compiler Macros](http://haxe.org/manual/macros_compiler) -* [Tips and Tricks](http://haxe.org/manual/tips_and_tricks) - - -Finally, please join us on [the mailing list](https://groups.google.com/forum/#!forum/haxelang), on IRC [#haxe on -freenode](http://webchat.freenode.net/), or on -[Google+](https://plus.google.com/communities/103302587329918132234). +* [Abstract types](https://haxe.org/manual/types-abstract.html) +* [Macros](https://haxe.org/manual/macro.html) +* [Compiler Features](https://haxe.org/manual/cr-features.html) +Finally, please join us on [the Haxe forum](https://community.haxe.org/), +on IRC [#haxe on +freenode](http://webchat.freenode.net/), or on the +[Haxe Gitter chat](https://gitter.im/HaxeFoundation/haxe). diff --git a/it-it/matlab-it.html.markdown b/it-it/matlab-it.html.markdown index 8d6d4385..38be8848 100644 --- a/it-it/matlab-it.html.markdown +++ b/it-it/matlab-it.html.markdown @@ -199,8 +199,7 @@ size(A) % ans = 3 3 A(1, :) =[] % Rimuove la prima riga della matrice A(:, 1) =[] % Rimuove la prima colonna della matrice -transpose(A) % Traspone la matrice, equivale a: -A one +transpose(A) % Traspone la matrice, equivale a: A.' ctranspose(A) % Trasposizione hermitiana della matrice % (ovvero il complesso coniugato di ogni elemento della matrice trasposta) diff --git a/java.html.markdown b/java.html.markdown index ab2be4a2..ca0b04c2 100644 --- a/java.html.markdown +++ b/java.html.markdown @@ -11,6 +11,7 @@ contributors: - ["Michael Dähnert", "https://github.com/JaXt0r"] - ["Rob Rose", "https://github.com/RobRoseKnows"] - ["Sean Nam", "https://github.com/seannam"] + - ["Shawn M. Hanes", "https://github.com/smhanes15"] filename: LearnJava.java --- @@ -858,6 +859,108 @@ public class EnumTest { // The enum body can include methods and other fields. // You can see more at https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html +// Getting Started with Lambda Expressions +// +// New to Java version 8 are lambda expressions. Lambdas are more commonly found +// in functional programming languages, which means they are methods which can +// be created without belonging to a class, passed around as if it were itself +// an object, and executed on demand. +// +// Final note, lambdas must implement a functional interface. A functional +// interface is one which has only a single abstract method declared. It can +// have any number of default methods. Lambda expressions can be used as an +// instance of that functional interface. Any interface meeting the requirements +// is treated as a functional interface. You can read more about interfaces +// above. +// +import java.util.Map; +import java.util.HashMap; +import java.util.function.*; +import java.security.SecureRandom; + +public class Lambdas { + public static void main(String[] args) { + // Lambda declaration syntax: + // <zero or more parameters> -> <expression body or statement block> + + // We will use this hashmap in our examples below. + Map<String, String> planets = new HashMap<>(); + planets.put("Mercury", "87.969"); + planets.put("Venus", "224.7"); + planets.put("Earth", "365.2564"); + planets.put("Mars", "687"); + planets.put("Jupiter", "4,332.59"); + planets.put("Saturn", "10,759"); + planets.put("Uranus", "30,688.5"); + planets.put("Neptune", "60,182"); + + // Lambda with zero parameters using the Supplier functional interface + // from java.util.function.Supplier. The actual lambda expression is + // what comes after numPlanets =. + Supplier<String> numPlanets = () -> Integer.toString(planets.size()); + System.out.format("Number of Planets: %s\n\n", numPlanets.get()); + + // Lambda with one parameter and using the Consumer functional interface + // from java.util.function.Consumer. This is because planets is a Map, + // which implements both Collection and Iterable. The forEach used here, + // found in Iterable, applies the lambda expression to each member of + // the Collection. The default implementation of forEach behaves as if: + /* + for (T t : this) + action.accept(t); + */ + + // The actual lambda expression is the parameter passed to forEach. + planets.keySet().forEach((p) -> System.out.format("%s\n", p)); + + // If you are only passing a single argument, then the above can also be + // written as (note absent parentheses around p): + planets.keySet().forEach(p -> System.out.format("%s\n", p)); + + // Tracing the above, we see that planets is a HashMap, keySet() returns + // a Set of its keys, forEach applies each element as the lambda + // expression of: (parameter p) -> System.out.format("%s\n", p). Each + // time, the element is said to be "consumed" and the statement(s) + // referred to in the lambda body is applied. Remember the lambda body + // is what comes after the ->. + + // The above without use of lambdas would look more traditionally like: + for (String planet : planets.keySet()) { + System.out.format("%s\n", planet); + } + + // This example differs from the above in that a different forEach + // implementation is used: the forEach found in the HashMap class + // implementing the Map interface. This forEach accepts a BiConsumer, + // which generically speaking is a fancy way of saying it handles + // the Set of each Key -> Value pairs. This default implementation + // behaves as if: + /* + for (Map.Entry<K, V> entry : map.entrySet()) + action.accept(entry.getKey(), entry.getValue()); + */ + + // The actual lambda expression is the parameter passed to forEach. + String orbits = "%s orbits the Sun in %s Earth days.\n"; + planets.forEach((K, V) -> System.out.format(orbits, K, V)); + + // The above without use of lambdas would look more traditionally like: + for (String planet : planets.keySet()) { + System.out.format(orbits, planet, planets.get(planet)); + } + + // Or, if following more closely the specification provided by the + // default implementation: + for (Map.Entry<String, String> planet : planets.entrySet()) { + System.out.format(orbits, planet.getKey(), planet.getValue()); + } + + // These examples cover only the very basic use of lambdas. It might not + // seem like much or even very useful, but remember that a lambda can be + // created as an object that can later be passed as parameters to other + // methods. + } +} ``` ## Further Reading diff --git a/javascript.html.markdown b/javascript.html.markdown index 52084e93..ecaf02c5 100644 --- a/javascript.html.markdown +++ b/javascript.html.markdown @@ -266,6 +266,15 @@ for (var x in person){ description += person[x] + " "; } // description = 'Paul Ken 18 ' +// The for/of statement allows iteration over iterable objects (including the built-in String, +// Array, e.g. the Array-like arguments or NodeList objects, TypedArray, Map and Set, +// and user-defined iterables). +var myPets = ""; +var pets = ["cat", "dog", "hamster", "hedgehog"]; +for (var pet of pets){ + myPets += pet + " "; +} // myPets = 'cat dog hamster hedgehog ' + // && is logical and, || is logical or if (house.size == "big" && house.colour == "blue"){ house.contains = "bear"; diff --git a/julia.html.markdown b/julia.html.markdown index 891a0a00..15c09da4 100644 --- a/julia.html.markdown +++ b/julia.html.markdown @@ -8,12 +8,12 @@ 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. +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 1.0.0 ```julia - # Single line comments start with a hash (pound) symbol. #= Multiline comments can be written by putting '#=' before the text and '=#' @@ -27,17 +27,17 @@ This is based on Julia 1.0.0 # 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}) +typeof(3) # => Int64 +typeof(3.2) # => Float64 +typeof(2 + 1im) # => Complex{Int64} +typeof(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 integers always results in a Float64 +10 / 2 # => 5.0 # 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 @@ -88,7 +88,9 @@ false # 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 +ascii("This is a string")[1] +# => 'T': ASCII/Unicode U+0054 (category Lu: Letter, uppercase) +# Julia indexes from 1 # Otherwise, iterating over strings is recommended (map, for loops, etc). # $ can be used for string interpolation: @@ -100,7 +102,7 @@ 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!") +println("I'm Julia. Nice to meet you!") # => I'm Julia. Nice to meet you! # String can be compared lexicographically "good" > "bye" # => true @@ -146,19 +148,19 @@ 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 Array{Int64,1} # 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 = [4, 5, 6] # => 3-element Array{Int64,1}: [4, 5, 6] +b = [4; 5; 6] # => 3-element Array{Int64,1}: [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] # => 2×2 Array{Int64,2}: [1 2; 3 4] # Arrays of a particular type -b = Int8[4, 5, 6] # => 3-element Int8 Array: [4, 5, 6] +b = Int8[4, 5, 6] # => 3-element Array{Int8,1}: [4, 5, 6] # Add stuff to the end of a list with push! and append! push!(a, 1) # => [1] @@ -168,10 +170,12 @@ 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 +b # => [4,5] # Let's put it back -push!(b, 6) # b is now [4,5,6] again. +push!(b, 6) # => [4,5,6] +b # => [4,5,6] a[1] # => 1 # remember that Julia indexes from 1, not 0! @@ -180,21 +184,37 @@ a[1] # => 1 # remember that Julia indexes from 1, not 0! a[end] # => 6 # we also have popfirst! and pushfirst! -popfirst!(a) # => 1 and a is now [2,4,3,4,5,6] +popfirst!(a) # => 1 +a # => [2,4,3,4,5,6] pushfirst!(a, 7) # => [7,2,4,3,4,5,6] +a # => [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 Array{Int64,1}: [5,4,6] +sort(arr) # => [4,5,6] +arr # => [5,4,6] +sort!(arr) # => [4,5,6] +arr # => [4,5,6] # Looking out of bounds is a BoundsError try - 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] + a[0] + # => ERROR: BoundsError: attempt to access 7-element Array{Int64,1} at + # index [0] + # => Stacktrace: + # => [1] getindex(::Array{Int64,1}, ::Int64) at .\array.jl:731 + # => [2] top-level scope at none:0 + # => [3] ... + # => in expression starting at ...\LearnJulia.jl:180 + a[end + 1] + # => ERROR: BoundsError: attempt to access 7-element Array{Int64,1} at + # index [8] + # => Stacktrace: + # => [1] getindex(::Array{Int64,1}, ::Int64) at .\array.jl:731 + # => [2] top-level scope at none:0 + # => [3] ... + # => in expression starting at ...\LearnJulia.jl:188 catch e println(e) end @@ -204,7 +224,8 @@ end # 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 Array{Int64,1}: [1,2,3,4,5] +a2 = [1:5] # => 1-element Array{UnitRange{Int64},1}: [1:5] # You can look at ranges with slice syntax. a[1:3] # => [1, 2, 3] @@ -212,11 +233,13 @@ 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 # => [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) # => [1, 2, 3, 4, 5, 1, 2, 3] +a # => [1, 2, 3, 4, 5, 1, 2, 3] # Check for existence in a list with in in(1, a) # => true @@ -225,39 +248,50 @@ in(1, a) # => true length(a) # => 8 # Tuples are immutable. -tup = (1, 2, 3) # => (1,2,3) # an (Int64,Int64,Int64) tuple. -tup[1] # => 1 +tup = (1, 2, 3) # => (1,2,3) +typeof(tup) # => Tuple{Int64,Int64,Int64} +tup[1] # => 1 try - tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64) + tup[1] = 3 + # => ERROR: MethodError: no method matching + # setindex!(::Tuple{Int64,Int64,Int64}, ::Int64, ::Int64) catch e println(e) end # Many array functions also work on tuples -length(tup) # => 3 -tup[1:2] # => (1,2) +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 # => 1 +b # => 2 +c # => 3 # Tuples are created even if you leave out the parentheses d, e, f = 4, 5, 6 # => (4,5,6) +d # => 4 +e # => 5 +f # => 6 # A 1-element tuple is distinct from the value it contains -(1,) == 1 # => false +(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 # => 5 +e # => 4 # Dictionaries store mappings -empty_dict = Dict() # => Dict{Any,Any}() +empty_dict = Dict() # => Dict{Any,Any} with 0 entries # You can create a dictionary using a literal filled_dict = Dict("one" => 1, "two" => 2, "three" => 3) -# => Dict{String,Int64} +# => Dict{String,Int64} with 3 entries: +# => "two" => 2, "one" => 1, "three" => 3 # Look up values with [] filled_dict["one"] # => 1 @@ -265,12 +299,13 @@ filled_dict["one"] # => 1 # Get all keys keys(filled_dict) # => Base.KeySet for a Dict{String,Int64} with 3 entries. Keys: -# "two", "one", "three" +# => "two", "one", "three" # Note - dictionary keys are not sorted or in the order you inserted them. # Get all values values(filled_dict) -# => Base.ValueIterator{Dict{String,Int64}} with 3 entries. Values: 2, 1, 3 +# => Base.ValueIterator for a 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 @@ -281,7 +316,7 @@ haskey(filled_dict, 1) # => false # Trying to look up a non-existent key will raise an error try - filled_dict["four"] # => KeyError: key "four" not found + filled_dict["four"] # => ERROR: KeyError: key "four" not found catch e println(e) end @@ -292,7 +327,7 @@ 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([4, 2, 3, 1]) @@ -300,15 +335,14 @@ filled_set = Set([1, 2, 2, 3, 4]) # => Set([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(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([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]) - +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]) #################################################### ## 3. Control Flow @@ -327,43 +361,38 @@ else # The else clause is optional too. end # => prints "some var is smaller than 10" - # For loops iterate over iterables. # Iterable types include Range, Array, Set, Dict, and AbstractString. for animal = ["dog", "cat", "mouse"] println("$animal is a mammal") # You can use $ to interpolate variables or expression into strings end -# prints: -# dog is a mammal -# cat is a mammal -# mouse is a mammal +# => dog is a mammal +# => cat is a mammal +# => mouse is a mammal # You can use 'in' instead of '='. for animal in ["dog", "cat", "mouse"] println("$animal is a mammal") end -# prints: -# dog is a mammal -# cat is a mammal -# mouse is a mammal +# => dog is a mammal +# => cat is a mammal +# => mouse is a mammal 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 +# => mouse is a mammal +# => cat is a mammal +# => dog is a mammal for (k, v) in Dict("dog" => "mammal", "cat" => "mammal", "mouse" => "mammal") println("$k is a $v") end -# prints: -# dog is a mammal -# cat is a mammal -# mouse is a mammal +# => mouse is a mammal +# => cat is a mammal +# => dog is a mammal # While loops loop while a condition is true let x = 0 @@ -372,11 +401,10 @@ let x = 0 x += 1 # Shorthand for x = x + 1 end end -# prints: -# 0 -# 1 -# 2 -# 3 +# => 0 +# => 1 +# => 2 +# => 3 # Handle exceptions with a try/catch block try @@ -386,15 +414,14 @@ catch e end # => caught it ErrorException("help") - #################################################### ## 4. Functions #################################################### # The keyword 'function' creates new functions -#function name(arglist) -# body... -#end +# function name(arglist) +# body... +# end function add(x, y) println("x is $x and y is $y") @@ -402,14 +429,16 @@ function add(x, y) x + y end -add(5, 6) # => 11 after printing out "x is 5 and y is 6" +add(5, 6) +# => x is 5 and y is 6 +# => 11 # Compact assignment of functions -f_add(x, y) = x + y # => "f (generic function with 1 method)" +f_add(x, y) = x + y # => f_add (generic function with 1 method) f_add(3, 4) # => 7 # Function can also return multiple values as tuple -fn(x, y) = x + y, x - y +fn(x, y) = x + y, x - y # => fn (generic function with 1 method) fn(3, 4) # => (7, -1) # You can define functions that take a variable number of @@ -436,13 +465,14 @@ add(x...) # this is equivalent to add(5,6) function defaults(a, b, x=5, y=6) return "$a $b and $x $y" end +# => defaults (generic function with 3 methods) 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: MethodError: no method matching defaults(::Char) + defaults() # => ERROR: MethodError: no method matching defaults() catch e println(e) end @@ -451,10 +481,11 @@ end function keyword_args(;k1=4, name2="hello") # note the ; return Dict("k1" => k1, "name2" => name2) end +# => keyword_args (generic function with 1 method) -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") # => ["name2"=>"hello", "k1"=>"mine"] +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") @@ -462,12 +493,12 @@ function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo") println("optional arg: $optional_positional_arg") println("keyword arg: $keyword_arg") end +# => all_the_args (generic function with 2 methods) all_the_args(1, 3, keyword_arg=4) -# prints: -# normal arg: 1 -# optional arg: 3 -# keyword arg: 4 +# => normal arg: 1 +# => optional arg: 3 +# => keyword arg: 4 # Julia has first class functions function create_adder(x) @@ -476,6 +507,7 @@ function create_adder(x) end return adder end +# => create_adder (generic function with 1 method) # This is "stabby lambda syntax" for creating anonymous functions (x -> x > 2)(3) # => true @@ -484,6 +516,7 @@ end function create_adder(x) y -> x + y end +# => create_adder (generic function with 1 method) # You can also name the internal function, if you want function create_adder(x) @@ -492,9 +525,11 @@ function create_adder(x) end adder end +# => create_adder (generic function with 1 method) -add_10 = create_adder(10) -add_10(3) # => 13 +add_10 = create_adder(10) # => (::getfield(Main, Symbol("#adder#11")){Int64}) + # (generic function with 1 method) +add_10(3) # => 13 # There are built-in higher order functions @@ -502,8 +537,8 @@ 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 -[add_10(i) for i = [1, 2, 3]] # => [11, 12, 13] -[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] +[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] #################################################### @@ -516,7 +551,7 @@ filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7] typeof(5) # => Int64 # Types are first-class values -typeof(Int64) # => DataType +typeof(Int64) # => DataType typeof(DataType) # => DataType # DataType is the type that represents types, including itself. @@ -551,32 +586,31 @@ sherekhan = typeof(tigger)(5.6, "fire") # => Tiger(5.6,"fire") 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}: - # Complex{T<:Real} - # Real + # => Complex + # => Real subtypes(Cat) # => 0-element Array{Any,1} # AbstractString, as the name implies, is also an abstract type -subtypes(AbstractString) # 4-element Array{Any,1}: - # String - # SubString - # SubstitutionString - # Test.GenericString +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 +typeof(5) # => Int64 +supertype(Int64) # => Signed +supertype(Signed) # => Integer supertype(Integer) # => Real -supertype(Real) # => Number -supertype(Number) # => Any +supertype(Real) # => Number +supertype(Number) # => Any supertype(supertype(Signed)) # => Real -supertype(Any) # => Any +supertype(Any) # => Any # All of these type, except for Int64, are abstract. -typeof("fire") # => String -supertype(String) # => AbstractString +typeof("fire") # => String +supertype(String) # => AbstractString # Likewise here with String supertype(SubString) # => AbstractString @@ -625,23 +659,24 @@ function meow(animal::Tiger) end # Testing the meow function -meow(tigger) # => "rawwr" +meow(tigger) # => "rawwwr" meow(Lion("brown", "ROAAR")) # => "ROAAR" -meow(Panther()) # => "grrr" +meow(Panther()) # => "grrr" # Review the local type hierarchy -Tiger <: Cat # => false -Lion <: Cat # => true -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))") end +# => pet_cat (generic function with 1 method) -pet_cat(Lion("42")) # => prints "The cat says 42" +pet_cat(Lion("42")) # => The cat says 42 try - pet_cat(tigger) # => ERROR: no method pet_cat(Tiger,) + pet_cat(tigger) # => ERROR: MethodError: no method matching pet_cat(::Tiger) catch e println(e) end @@ -656,45 +691,54 @@ function fight(t::Tiger, c::Cat) 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()) # => The orange tiger wins! +fight(tigger, Lion("ROAR")) # => 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 (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()) # => The orange tiger wins! +fight(tigger, Lion("ROAR")) # => 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 (generic function with 3 methods) -fight(Lion("balooga!"), Panther()) # => prints The victorious cat says grrr +fight(Lion("balooga!"), Panther()) # => The victorious cat says grrr try - fight(Panther(), Lion("RAWR")) + fight(Panther(), Lion("RAWR")) + # => ERROR: MethodError: no method matching fight(::Panther, ::Lion) + # => Closest candidates are: + # => fight(::Tiger, ::Lion) at ... + # => fight(::Tiger, ::Cat) at ... + # => fight(::Lion, ::Cat) at ... + # => ... 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") +# => fight (generic function with 4 methods) # This warning is because it's unclear which fight will be called in: try fight(Lion("RAR"), Lion("brown", "rarrr")) - # => prints The victorious cat says rarrr + # => ERROR: MethodError: fight(::Lion, ::Lion) is ambiguous. Candidates: + # => fight(c::Cat, l::Lion) in Main at ... + # => fight(l::Lion, c::Cat) in Main at ... + # => Possible fix, define + # => fight(::Lion, ::Lion) + # => ... 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 (generic function with 5 methods) +fight(Lion("RAR"), Lion("brown", "rarrr")) # => The lions come to a tie # Under the hood @@ -705,74 +749,112 @@ square_area(l) = l * l # square_area (generic function with 1 method) 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 - -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 - -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 - # +code_native(square_area, (Int32,), syntax = :intel) + # .text + # ; Function square_area { + # ; Location: REPL[116]:1 # Prologue + # push rbp + # mov rbp, rsp + # ; Function *; { + # ; Location: int.jl:54 + # imul ecx, ecx # Square l and store the result in ECX + # ;} + # mov eax, ecx + # pop rbp # Restore old base pointer + # ret # Result will still be in EAX + # nop dword ptr [rax + rax] + # ;} + +code_native(square_area, (Float32,), syntax = :intel) + # .text + # ; Function square_area { + # ; Location: REPL[116]:1 + # push rbp + # mov rbp, rsp + # ; Function *; { + # ; Location: float.jl:398 + # vmulss xmm0, xmm0, xmm0 # Scalar single precision multiply (AVX) + # ;} + # pop rbp + # ret + # nop word ptr [rax + rax] + # ;} + +code_native(square_area, (Float64,), syntax = :intel) + # .text + # ; Function square_area { + # ; Location: REPL[116]:1 + # push rbp + # mov rbp, rsp + # ; Function *; { + # ; Location: float.jl:399 + # vmulsd xmm0, xmm0, xmm0 # Scalar double precision multiply (AVX) + # ;} + # pop rbp + # ret + # nop word ptr [rax + rax] + # ;} + # 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 -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 - # - -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 - # +code_native(circle_area, (Int32,), syntax = :intel) + # .text + # ; Function circle_area { + # ; Location: REPL[121]:1 + # push rbp + # mov rbp, rsp + # ; Function *; { + # ; Location: operators.jl:502 + # ; Function *; { + # ; Location: promotion.jl:314 + # ; Function promote; { + # ; Location: promotion.jl:284 + # ; Function _promote; { + # ; Location: promotion.jl:261 + # ; Function convert; { + # ; Location: number.jl:7 + # ; Function Type; { + # ; Location: float.jl:60 + # vcvtsi2sd xmm0, xmm0, ecx # Load integer (r) from memory + # movabs rax, 497710928 # Load pi + # ;}}}}} + # ; Function *; { + # ; Location: float.jl:399 + # vmulsd xmm1, xmm0, qword ptr [rax] # pi * r + # vmulsd xmm0, xmm1, xmm0 # (pi * r) * r + # ;}} + # pop rbp + # ret + # nop dword ptr [rax] + # ;} + +code_native(circle_area, (Float64,), syntax = :intel) + # .text + # ; Function circle_area { + # ; Location: REPL[121]:1 + # push rbp + # mov rbp, rsp + # movabs rax, 497711048 + # ; Function *; { + # ; Location: operators.jl:502 + # ; Function *; { + # ; Location: promotion.jl:314 + # ; Function *; { + # ; Location: float.jl:399 + # vmulsd xmm1, xmm0, qword ptr [rax] + # ;}}} + # ; Function *; { + # ; Location: float.jl:399 + # vmulsd xmm0, xmm1, xmm0 + # ;} + # pop rbp + # ret + # nop dword ptr [rax + rax] + # ;} ``` ## Further Reading diff --git a/lua.html.markdown b/lua.html.markdown index 1e2d4366..32174a81 100644 --- a/lua.html.markdown +++ b/lua.html.markdown @@ -62,6 +62,11 @@ if not aBoolValue then print('twas false') end -- in C/js: ans = aBoolValue and 'yes' or 'no' --> 'no' +-- BEWARE: this only acts as a ternary if the value returned when the condition +-- evaluates to true is not `false` or Nil +iAmNotFalse = (not aBoolValue) and false or true --> true +iAmAlsoNotFalse = (not aBoolValue) and true or false --> true + karlSum = 0 for i = 1, 100 do -- The range includes both ends. karlSum = karlSum + i diff --git a/matlab.html.markdown b/matlab.html.markdown index b88b1c03..5790bcc6 100644 --- a/matlab.html.markdown +++ b/matlab.html.markdown @@ -221,11 +221,11 @@ A(1, :) =[] % Delete the first row of the matrix A(:, 1) =[] % Delete the first column of the matrix transpose(A) % Transpose the matrix, which is the same as: -A one -ctranspose(A) % Hermitian transpose the matrix -% (the transpose, followed by taking complex conjugate of each element) -A' % Concise version of complex transpose A.' % Concise version of transpose (without taking complex conjugate) +ctranspose(A) % Hermitian transpose the matrix, which is the same as: +A' % Concise version of complex transpose + % (the transpose, followed by taking complex conjugate of each element) + diff --git a/montilang.html.markdown b/montilang.html.markdown new file mode 100644 index 00000000..cceb7aa1 --- /dev/null +++ b/montilang.html.markdown @@ -0,0 +1,233 @@ +--- +language: "montilang" +filename: montilang.ml +contributors: + - ["Leo Whitehead", "https://github.com/lduck11007"] +--- + +MontiLang is a Stack-Oriented concatenative imperative programming language. Its syntax +is roughly based off of forth with similar style for doing arithmetic in [reverse polish notation.](https://en.wikipedia.org/wiki/Reverse_Polish_notation) + +A good way to start with MontiLang is to read the documentation and examples at [montilang.ml](http://montilang.ml), +then download MontiLang or build from source code with the instructions provided. + +``` +/# Monti Reference sheet #/ +/# +Comments are multiline +Nested comments are not supported +#/ +/# Whitespace is all arbitrary, indentation is optional #/ +/# All programming in Monti is done by manipulating the parameter stack +arithmetic and stack operations in MontiLang are similar to FORTH +https://en.wikipedia.org/wiki/Forth_(programming_language) +#/ + +/# in Monti, everything is either a string or a number. Operations treat all numbers +similarly to floats, but anything without a remainder is treated as type int #/ + +/# numbers and strings are added to the stack from left to right #/ + +/# Arithmetic works by manipulating data on the stack #/ + +5 3 + PRINT . /# 8 #/ + +/# 5 and 3 are pushed onto the stack + '+' replaces top 2 items on stack with sum of top 2 items + 'PRINT' prints out the top item on the stack + '.' pops the top item from the stack. + #/ + +6 7 * PRINT . /# 42 #/ +1360 23 - PRINT . /# 1337 #/ +12 12 / PRINT . /# 1 #/ +13 2 % PRINT . /# 1 #/ + +37 NEG PRINT . /# -37 #/ +-12 ABS PRINT . /# 12 #/ +52 23 MAX PRINT . /# 52 #/ +52 23 MIN PRINT . /# 23 #/ + +/# 'PSTACK' command prints the entire stack, 'CLEAR' clears the entire stack #/ + +3 6 8 PSTACK CLEAR /# [3, 6, 8] #/ + +/# Monti comes with some tools for stack manipulation #/ + +2 DUP PSTACK CLEAR /# [2, 2] - Duplicate the top item on the stack#/ +2 6 SWAP PSTACK CLEAR /# [6, 2] - Swap top 2 items on stack #/ +1 2 3 ROT PSTACK CLEAR /# [2, 3, 1] - Rotate top 3 items on stack #/ +2 3 NIP PSTACK CLEAR /# [3] - delete second item from the top of the stack #/ +4 5 6 TRIM PSTACK CLEAR /# [5, 6] - Deletes first item on stack #/ +/# variables are assigned with the syntax 'VAR [name]'#/ +/# When assigned, the variable will take the value of the top item of the stack #/ + +6 VAR six . /# assigns var 'six' to be equal to 6 #/ +3 6 + VAR a . /# assigns var 'a' to be equal to 9 #/ + +/# the length of the stack can be calculated with the statement 'STKLEN' #/ +1 2 3 4 STKLEN PRINT CLEAR /# 4 #/ + +/# strings are defined with | | #/ + +|Hello World!| VAR world . /# sets variable 'world' equal to string 'Hello world! #/ + +/# variables can be called by typing its name. when called, the value of the variable is pushed +to the top of the stack #/ +world PRINT . + +/# with the OUT statement, the top item on the stack can be printed without a newline #/ + +|world!| |Hello, | OUT SWAP PRINT CLEAR + +/# Data types can be converted between strings and integers with the commands 'TOINT' and 'TOSTR'#/ +|5| TOINT PSTACK . /# [5] #/ +45 TOSTR PSTACK . /# ['45'] #/ + +/# User input is taken with INPUT and pushed to the stack. If the top item of the stack is a string, +the string is used as an input prompt #/ + +|What is your name? | INPUT NIP +|Hello, | OUT SWAP PRINT CLEAR + + +/# FOR loops have the syntax 'FOR [condition] [commands] ENDFOR' At the moment, [condition] can +only have the value of an integer. Either by using an integer, or a variable call to an integer. +[commands] will be interpereted the amount of time specified in [condition] #/ +/# E.G: this prints out 1 to 10 #/ + +1 VAR a . +FOR 10 + a PRINT 1 + VAR a +ENDFOR + +/# the syntax for while loops are similar. A number is evaluated as true if it is larger than +0. a string is true if its length > 0. Infinite loops can be used by using literals. +#/ +10 var loop . +WHILE loop + loop print + 1 - var loop +ENDWHILE +/# +this loop would count down from 10. + +IF statements are pretty much the same, but only are executed once. +#/ +IF loop + loop PRINT . +ENDIF + +/# This would only print 'loop' if it is larger than 0 #/ + +/# If you would want to use the top item on the stack as loop parameters, this can be done with the ':' character #/ + +/# eg, if you wanted to print 'hello' 7 times, instead of using #/ + +FOR 7 + |hello| PRINT . +ENDFOR + +/# this could be used #/ +7 +FOR : + |hello| PRINT . +ENDFOR + +/# Equality and inequality statements use the top 2 items on the stack as parameters, and replace the top two items with the output #/ +/# If it is true, the top 2 items are replaced with '1'. If false, with '0'. #/ + +7 3 > PRINT . /# 1 #/ +2 10 > PRINT . /# 0 #/ +5 9 <= PRINT . /# 1 #/ +5 5 == PRINT . /# 1 #/ +5 7 == PRINT . /# 0 #/ +3 8 != PRINT . /# 1 #/ + +/# User defined commands have the syntax of 'DEF [name] [commands] ENDDEF'. #/ +/# eg, if you wanted to define a function with the name of 'printseven' to print '7' 10 times, this could be used #/ + +DEF printseven + FOR 10 + 7 PRINT . + ENDFOR +ENDDEF + +/# to run the defined statement, simply type it and it will be run by the interpereter #/ + +printseven + +/# Montilang supports AND, OR and NOT statements #/ + +1 0 AND PRINT . /# 0 #/ +1 1 AND PRINT . /# 1 #/ +1 0 OR PRINT . /# 1 #/ +0 0 OR PRINT . /# 0 #/ +1 NOT PRINT . /# 0 #/ +0 NOT PRINT . /# 1 #/ + +/# Preprocessor statements are made inbetween '&' characters #/ +/# currently, preprocessor statements can be used to make c++-style constants #/ + +&DEFINE LOOPSTR 20& +/# must have & on either side with no spaces, 'DEFINE' is case sensative. #/ +/# All statements are scanned and replaced before the program is run, regardless of where the statements are placed #/ + +FOR LOOPSTR 7 PRINT . ENDFOR /# Prints '7' 20 times. At run, 'LOOPSTR' in source code is replaced with '20' #/ + +/# Multiple files can be used with the &INCLUDE <filename>& Command that operates similar to c++, where the file specified is tokenized, + and the &INCLUDE statement is replaced with the file #/ + +/# E.G, you can have a program be run through several files. If you had the file 'name.mt' with the following data: + +[name.mt] +|Hello, | OUT . name PRINT . + +a program that asks for your name and then prints it out can be defined as such: #/ + +|What is your name? | INPUT VAR name . &INCLUDE name.mt& + +/# ARRAYS: #/ + +/# arrays are defined with the statement 'ARR' +When called, everything currently in the stack is put into one +array and all items on the stack are replaced with the new array. #/ + +2 3 4 ARR PSTACK . /# [[2, 3, 4]] #/ + +/# the statement 'LEN' adds the length of the last item on the stack to the stack. +This can be used on arrays, as well as strings. #/ + +3 4 5 ARR LEN PRINT . /# 3 #/ + +/# values can be appended to an array with the statement 'APPEND' #/ + +1 2 3 ARR 5 APPEND . PRINT . /# [1, 2, 3, 5] #/ + +/# an array at the top of the stack can be wiped with the statement 'WIPE' #/ +3 4 5 ARR WIPE PRINT . /# [] #/ + +/# The last item of an array can be removed with the statement 'DROP' #/ + +3 4 5 ARR DROP PRINT . /# [3, 4] +/# arrays, like other datatypes can be stored in variables #/ +5 6 7 ARR VAR list . +list PRINT . /# [5, 6, 7] #/ + +/# Values at specific indexes can be changed with the statement 'INSERT <index>' #/ +4 5 6 ARR +97 INSERT 1 . PRINT /# 4, 97, 6 #/ + +/# Values at specific indexes can be deleted with the statement 'DEL <index>' #/ +1 2 3 ARR +DEL 1 PRINT . /# [1, 3] #/ + +/# items at certain indexes of an array can be gotten with the statement 'GET <index>' #/ + +1 2 3 ARR GET 2 PSTACK /# [[1, 2, 3], 3] #/ +``` + +## Extra information + +- [MontiLang.ml](http://montilang.ml/) +- [Github Page](https://github.com/lduck11007/MontiLang) diff --git a/moonscript.html.markdown b/moonscript.html.markdown new file mode 100644 index 00000000..941578e7 --- /dev/null +++ b/moonscript.html.markdown @@ -0,0 +1,570 @@ +--- +language: moonscript +contributors: + - ["RyanSquared", "https://ryansquared.github.io/"] + - ["Job van der Zwan", "https://github.com/JobLeonard"] +filename: moonscript.moon +--- + +MoonScript is a dynamic scripting language that compiles into Lua. It gives +you the power of one of the fastest scripting languages combined with a +rich set of features. + +See [the MoonScript website](https://moonscript.org/) to see official guides on installation for all platforms. + +```moon +-- Two dashes start a comment. Comments can go until the end of the line. +-- MoonScript transpiled to Lua does not keep comments. + +-- As a note, MoonScript does not use 'do', 'then', or 'end' like Lua would and +-- instead uses an indented syntax, much like Python. + +-------------------------------------------------- +-- 1. Assignment +-------------------------------------------------- + +hello = "world" +a, b, c = 1, 2, 3 +hello = 123 -- Overwrites `hello` from above. + +x = 0 +x += 10 -- x = x + 10 + +s = "hello " +s ..= "world" -- s = s .. "world" + +b = false +b and= true or false -- b = b and (true or false) + +-------------------------------------------------- +-- 2. Literals and Operators +-------------------------------------------------- + +-- Literals work almost exactly as they would in Lua. Strings can be broken in +-- the middle of a line without requiring a \. + +some_string = "exa +mple" -- local some_string = "exa\nmple" + +-- Strings can also have interpolated values, or values that are evaluated and +-- then placed inside of a string. + +some_string = "This is an #{some_string}" -- Becomes 'This is an exa\nmple' + +-------------------------------------------------- +-- 2.1. Function Literals +-------------------------------------------------- + +-- Functions are written using arrows: + +my_function = -> -- compiles to `function() end` +my_function() -- calls an empty function + +-- Functions can be called without using parenthesis. Parentheses may still be +-- used to have priority over other functions. + +func_a = -> print "Hello World!" +func_b = -> + value = 100 + print "The value: #{value}" + +-- If a function needs no parameters, it can be called with either `()` or `!`. + +func_a! +func_b() + +-- Functions can use arguments by preceding the arrow with a list of argument +-- names bound by parentheses. + +sum = (x, y)-> x + y -- The last expression is returned from the function. +print sum(5, 10) + +-- Lua has an idiom of sending the first argument to a function as the object, +-- like a 'self' object. Using a fat arrow (=>) instead of a skinny arrow (->) +-- automatically creates a `self` variable. `@x` is a shorthand for `self.x`. + +func = (num)=> @value + num + +-- Default arguments can also be used with function literals: + +a_function = (name = "something", height=100)-> + print "Hello, I am #{name}.\nMy height is #{height}." + +-- Because default arguments are calculated in the body of the function when +-- transpiled to Lua, you can reference previous arguments. + +some_args = (x = 100, y = x + 1000)-> print(x + y) + +-------------------------------------------------- +-- Considerations +-------------------------------------------------- + +-- The minus sign plays two roles, a unary negation operator and a binary +-- subtraction operator. It is recommended to always use spaces between binary +-- operators to avoid the possible collision. + +a = x - 10 -- a = x - 10 +b = x-10 -- b = x - 10 +c = x -y -- c = x(-y) +d = x- z -- d = x - z + +-- When there is no space between a variable and string literal, the function +-- call takes priority over following expressions: + +x = func"hello" + 100 -- func("hello") + 100 +y = func "hello" + 100 -- func("hello" + 100) + +-- Arguments to a function can span across multiple lines as long as the +-- arguments are indented. The indentation can be nested as well. + +my_func 5, -- called as my_func(5, 8, another_func(6, 7, 9, 1, 2), 5, 4) + 8, another_func 6, 7, -- called as + 9, 1, 2, -- another_func(6, 7, 9, 1, 2) + 5, 4 + +-- If a function is used at the start of a block, the indentation can be +-- different than the level of indentation used in a block: + +if func 1, 2, 3, -- called as func(1, 2, 3, "hello", "world") + "hello", + "world" + print "hello" + +-------------------------------------------------- +-- 3. Tables +-------------------------------------------------- + +-- Tables are defined by curly braces, like Lua: + +some_values = {1, 2, 3, 4} + +-- Tables can use newlines instead of commas. + +some_other_values = { + 5, 6 + 7, 8 +} + +-- Assignment is done with `:` instead of `=`: + +profile = { + name: "Bill" + age: 200 + "favorite food": "rice" +} + +-- Curly braces can be left off for `key: value` tables. + +y = type: "dog", legs: 4, tails: 1 + +profile = + height: "4 feet", + shoe_size: 13, + favorite_foods: -- nested table + foo: "ice cream", + bar: "donuts" + +my_function dance: "Tango", partner: "none" -- :( forever alone + +-- Tables constructed from variables can use the same name as the variables +-- by using `:` as a prefix operator. + +hair = "golden" +height = 200 +person = {:hair, :height} + +-- Like in Lua, keys can be non-string or non-numeric values by using `[]`. + +t = + [1 + 2]: "hello" + "hello world": true -- Can use string literals without `[]`. + +-------------------------------------------------- +-- 3.1. Table Comprehensions +-------------------------------------------------- + +-- List Comprehensions + +-- Creates a copy of a list but with all items doubled. Using a star before a +-- variable name or table can be used to iterate through the table's values. + +items = {1, 2, 3, 4} +doubled = [item * 2 for item in *items] +-- Uses `when` to determine if a value should be included. + +slice = [item for item in *items when i > 1 and i < 3] + +-- `for` clauses inside of list comprehensions can be chained. + +x_coords = {4, 5, 6, 7} +y_coords = {9, 2, 3} + +points = [{x,y} for x in *x_coords for y in *y_coords] + +-- Numeric for loops can also be used in comprehensions: + +evens = [i for i=1, 100 when i % 2 == 0] + +-- Table Comprehensions are very similar but use `{` and `}` and take two +-- values for each iteration. + +thing = color: "red", name: "thing", width: 123 +thing_copy = {k, v for k, v in pairs thing} + +-- Tables can be "flattened" from key-value pairs in an array by using `unpack` +-- to return both values, using the first as the key and the second as the +-- value. + +tuples = {{"hello", "world"}, {"foo", "bar"}} +table = {unpack tuple for tuple in *tuples} + +-- Slicing can be done to iterate over only a certain section of an array. It +-- uses the `*` notation for iterating but appends `[start, end, step]`. + +-- The next example also shows that this syntax can be used in a `for` loop as +-- well as any comprehensions. + +for item in *points[1, 10, 2] + print unpack item + +-- Any undesired values can be left off. The second comma is not required if +-- the step is not included. + +words = {"these", "are", "some", "words"} +for word in *words[,3] + print word + +-------------------------------------------------- +-- 4. Control Structures +-------------------------------------------------- + +have_coins = false +if have_coins + print "Got coins" +else + print "No coins" + +-- Use `then` for single-line `if` +if have_coins then "Got coins" else "No coins" + +-- `unless` is the opposite of `if` +unless os.date("%A") == "Monday" + print "It is not Monday!" + +-- `if` and `unless` can be used as expressions +is_tall = (name)-> if name == "Rob" then true else false +message = "I am #{if is_tall "Rob" then "very tall" else "not so tall"}" +print message -- "I am very tall" + +-- `if`, `elseif`, and `unless` can evaluate assignment as well as expressions. +if x = possibly_nil! -- sets `x` to `possibly_nil()` and evaluates `x` + print x + +-- Conditionals can be used after a statement as well as before. This is +-- called a "line decorator". + +is_monday = os.date("%A") == "Monday" +print("It IS Monday!") if isMonday +print("It is not Monday..") unless isMonday +--print("It IS Monday!" if isMonday) -- Not a statement, does not work + +-------------------------------------------------- +-- 4.1 Loops +-------------------------------------------------- + +for i = 1, 10 + print i + +for i = 10, 1, -1 do print i -- Use `do` for single-line loops. + +i = 0 +while i < 10 + continue if i % 2 == 0 -- Continue statement; skip the rest of the loop. + print i + +-- Loops can be used as a line decorator, just like conditionals +print "item: #{item}" for item in *items + +-- Using loops as an expression generates an array table. The last statement +-- in the block is coerced into an expression and added to the table. +my_numbers = for i = 1, 6 do i -- {1, 2, 3, 4, 5, 6} + +-- use `continue` to filter out values +odds = for i in *my_numbers + continue if i % 2 == 0 -- acts opposite to `when` in comprehensions! + i -- Only added to return table if odd + +-- A `for` loop returns `nil` when it is the last statement of a function +-- Use an explicit `return` to generate a table. +print_squared = (t) -> for x in *t do x*x -- returns `nil` +squared = (t) -> return for x in *t do x*x -- returns new table of squares + +-- The following does the same as `(t) -> [i for i in *t when i % 2 == 0]` +-- But list comprehension generates better code and is more readable! + +filter_odds = (t) -> + return for x in *t + if x % 2 == 0 then x else continue +evens = filter_odds(my_numbers) -- {2, 4, 6} + +-------------------------------------------------- +-- 4.2 Switch Statements +-------------------------------------------------- + +-- Switch statements are a shorthand way of writing multiple `if` statements +-- checking against the same value. The value is only evaluated once. + +name = "Dan" + +switch name + when "Dave" + print "You are Dave." + when "Dan" + print "You are not Dave, but Dan." + else + print "You are neither Dave nor Dan." + +-- Switches can also be used as expressions, as well as compare multiple +-- values. The values can be on the same line as the `when` clause if they +-- are only one expression. + +b = 4 +next_even = switch b + when 1 then 2 + when 2, 3 then 4 + when 4, 5 then 6 + else error "I can't count that high! D:" + +-------------------------------------------------- +-- 5. Object Oriented Programming +-------------------------------------------------- + +-- Classes are created using the `class` keyword followed by an identifier, +-- typically written using CamelCase. Values specific to a class can use @ as +-- the identifier instead of `self.value`. + +class Inventory + new: => @items = {} + add_item: (name)=> -- note the use of fat arrow for classes! + @items[name] = 0 unless @items[name] + @items[name] += 1 + +-- The `new` function inside of a class is special because it is called when +-- an instance of the class is created. + +-- Creating an instance of the class is as simple as calling the class as a +-- function. Calling functions inside of the class uses \ to separate the +-- instance from the function it is calling. + +inv = Inventory! +inv\add_item "t-shirt" +inv\add_item "pants" + +-- Values defined in the class - not the new() function - will be shared across +-- all instances of the class. + +class Person + clothes: {} + give_item: (name)=> + table.insert @clothes name + +a = Person! +b = Person! + +a\give_item "pants" +b\give_item "shirt" + +-- prints out both "pants" and "shirt" + +print item for item in *a.clothes + +-- Class instances have a value `.__class` that are equal to the class object +-- that created the instance. + +assert(b.__class == Person) + +-- Variables declared in class body the using the `=` operator are locals, +-- so these "private" variables are only accessible within the current scope. + +class SomeClass + x = 0 + reveal: -> + x += 1 + print x + +a = SomeClass! +b = SomeClass! +print a.x -- nil +a.reveal! -- 1 +b.reveal! -- 2 + +-------------------------------------------------- +-- 5.1 Inheritance +-------------------------------------------------- + +-- The `extends` keyword can be used to inherit properties and methods from +-- another class. + +class Backpack extends Inventory + size: 10 + add_item: (name)=> + error "backpack is full" if #@items > @size + super name -- calls Inventory.add_item with `name`. + +-- Because a `new` method was not added, the `new` method from `Inventory` will +-- be used instead. If we did want to use a constructor while still using the +-- constructor from `Inventory`, we could use the magical `super` function +-- during `new()`. + +-- When a class extends another, it calls the method `__inherited` on the +-- parent class (if it exists). It is always called with the parent and the +-- child object. + +class ParentClass + @__inherited: (child)=> + print "#{@__name} was inherited by #{child.__name}" + a_method: (a, b) => print a .. ' ' .. b + +-- Will print 'ParentClass was inherited by MyClass' + +class MyClass extends ParentClass + a_method: => + super "hello world", "from MyClass!" + assert super == ParentClass + +-------------------------------------------------- +-- 6. Scope +-------------------------------------------------- + +-- All values are local by default. The `export` keyword can be used to +-- declare the variable as a global value. + +export var_1, var_2 +var_1, var_3 = "hello", "world" -- var_3 is local, var_1 is not. + +export this_is_global_assignment = "Hi!" + +-- Classes can also be prefixed with `export` to make them global classes. +-- Alternatively, all CamelCase variables can be exported automatically using +-- `export ^`, and all values can be exported using `export *`. + +-- `do` lets you manually create a scope, for when you need local variables. + +do + x = 5 +print x -- nil + +-- Here we use `do` as an expression to create a closure. + +counter = do + i = 0 + -> + i += 1 + return i + +print counter! -- 1 +print counter! -- 2 + +-- The `local` keyword can be used to define variables +-- before they are assigned. + +local var_4 +if something + var_4 = 1 +print var_4 -- works because `var_4` was set in this scope, not the `if` scope. + +-- The `local` keyword can also be used to shadow an existing variable. + +x = 10 +if false + local x + x = 12 +print x -- 10 + +-- Use `local *` to forward-declare all variables. +-- Alternatively, use `local ^` to forward-declare all CamelCase values. + +local * + +first = -> + second! + +second = -> + print data + +data = {} + +-------------------------------------------------- +-- 6.1 Import +-------------------------------------------------- + +-- Values from a table can be brought to the current scope using the `import` +-- and `from` keyword. Names in the `import` list can be preceded by `\` if +-- they are a module function. + +import insert from table -- local insert = table.insert +import \add from state: 100, add: (value)=> @state + value +print add 22 + +-- Like tables, commas can be excluded from `import` lists to allow for longer +-- lists of imported items. + +import + asdf, gh, jkl + antidisestablishmentarianism + from {} + +-------------------------------------------------- +-- 6.2 With +-------------------------------------------------- + +-- The `with` statement can be used to quickly call and assign values in an +-- instance of a class or object. + +file = with File "lmsi15m.moon" -- `file` is the value of `set_encoding()`. + \set_encoding "utf8" + +create_person = (name, relatives)-> + with Person! + .name = name + \add_relative relative for relative in *relatives +me = create_person "Ryan", {"sister", "sister", "brother", "dad", "mother"} + +with str = "Hello" -- assignment as expression! :D + print "original: #{str}" + print "upper: #{\upper!}" + +-------------------------------------------------- +-- 6.3 Destructuring +-------------------------------------------------- + +-- Destructuring can take arrays, tables, and nested tables and convert them +-- into local variables. + +obj2 = + numbers: {1, 2, 3, 4} + properties: + color: "green" + height: 13.5 + +{numbers: {first, second}, properties: {:color}} = obj2 + +print first, second, color -- 1 2 green + +-- `first` and `second` return [1] and [2] because they are as an array, but +-- `:color` is like `color: color` so it sets itself to the `color` value. + +-- Destructuring can be used in place of `import`. + +{:max, :min, random: rand} = math -- rename math.random to rand + +-- Destructuring can be done anywhere assignment can be done. + +for {left, right} in *{{"hello", "world"}, {"egg", "head"}} + print left, right +``` + +## Additional Resources + +- [Language Guide](https://moonscript.org/reference/) +- [Online Compiler](https://moonscript.org/compiler/) diff --git a/processing.html.markdown b/processing.html.markdown new file mode 100644 index 00000000..fc5dc997 --- /dev/null +++ b/processing.html.markdown @@ -0,0 +1,421 @@ +--- +language: processing +filename: learnprocessing.pde +contributors: + - ["Phone Thant Ko", "http://github.com/phonethantko"] +--- +## Introduction + +Processing is a programming language for creation of digital arts and multimedia content, allowing non-programmers to +learn fundamentals of computer programming in a visual context. +While the language is based on Java language, +its syntax has been largely influenced by both Java and Javascript syntaxes. [See more here](https://processing.org/reference/) +The language is statically typed, and also comes with its official IDE to compile and run the scripts. + +```processing +/* --------- + Comments + --------- +*/ + +// Single-line comment starts with // + +/* + Since Processing is based on Java, + the syntax for its comments are the same as Java (as you may have noticed above)! + Multi-line comments are wrapped as seen here. +*/ + +/* --------------------------------------- + Writing and Running Processing Programs + --------------------------------------- + */ + +// In Processing, your program's entry point is a function named setup() with a void return type. +// Note! The syntax looks strikingly similar to that of C++. +void setup() { + // This prints out the classic output "Hello World!" to the console when run. + println("Hello World!"); // Another language with a semi-column trap, ain't it? +} + +// Normally, we put all the static codes inside the setup() method as the name suggest since it only runs once. +// It can range from setting the background colours, setting the canvas size. +background(color); // setting the background colour +size(width,height,[renderer]); // setting the canvas size with optional parameter defining renderer +// You will see more of them throughout this document. + +// If you want to run the codes indefinitely, it has to be placed in draw() method. +// draw() must exist if you want the code to run continuously and obviously, there can only be one draw() method. +int i = 0; +void draw() { + // This block of code loops forever until stopped + print(i); + i++; // Increment Operator! +} + +// Now that we know how to write the working script and how to run it, +// we will proceed to explore what data types and collections are supported in Processing. + +/* ------------------------ + Datatypes & collections + ------------------------ +*/ + +// According to Processing References, Processing supports 8 primitive datatypes as follows. + +boolean booleanValue = true; // Boolean +byte byteValueOfA = 23; // Byte +char charValueOfA = 'A'; // Char +color colourValueOfWhiteM = color(255, 255, 255); // Colour (Specified using color() method) +color colourValueOfWhiteH = #FFFFFF; // Colour (Specified using hash value) +int intValue = 5; // Integer (Number without decimals) +long longValue = 2147483648L; // "L" is added to the number to mark it as a long +float floatValue = 1.12345; // Float (32-bit floating-point numbers) +double doubleValue = 1.12345D; // Double (64-bit floating-point numbers) + +// NOTE! +// Although datatypes "long" and "double" work in the language, +// processing functions do not use these datatypes, therefore +// they need to be converted into "int" and "float" datatypes respectively, +// using (int) and (float) syntax before passing into a function. + +// There is a whole bunch of default composite datatypes available for use in Processing. +// Primarily, I will brief through the most commonly used ones to save time. + +// String +// While char datatype uses '', String datatype uses "" - double quotes. +String sampleString = "Hello, Processing!"; +// String can be constructed from an array of char datatypes as well. We will discuss array very soon. +char source = {'H', 'E', 'L', 'L', 'O'}; +String stringFromSource = new String(source); // HELLO +// As in Java, strings can be concatenated using the "+" operator. +print("Hello " + "World!"); // Hello World! + +// Array +// Arrays in Processing can hold any datatypes including Objects themselves. +// Since arrays are similar to objects, they must be created with the keyword "new". +int[] intArray = new int[5]; +int[] intArrayWithValues = {1, 2, 3}; // You can also populate with data. + +// ArrayList +// Functions are similar to those of array; arraylists can hold any datatypes. +// The only difference is arraylists resize dynamically, +// as it is a form of resizable-array implementation of the Java "List" interface. +ArrayList<Integer> intArrayList = new ArrayList<Integer>(); + +// Object +// Since it is based on Java, Processing supports object-oriented programming. +// That means you can basically define any datatypes of your own and manipulate them to your needs. +// Of course, a class has to be defined before for the object you want. +// Format --> ClassName InstanceName +SomeRandomClass myObject // then instantiate later +//or +SomeRandomClass myObjectInstantiated = new SomeRandomClass(); + +// Processing comes up with more collections (eg. - Dictionaries and Lists) by default, +// for the simplicity sake, I will leave them out of discussion here. + +/* ------------ + Maths + ------------ +*/ + +// Arithmetic +1 + 1 // 2 +2 - 1 // 0 +2 * 3 // 6 +3 / 2 // 1 +3.0 / 2 // 1.5 +3.0 % 2 // 1.0 + +// Processing also comes with a set of functions that simplify mathematical operations. +float f = sq(3); // f = 9.0 +float p = pow(3, 3); // p = 27.0 +int a = abs(-13) // a = 13 +int r1 = round(3.1); // r1 = 3 +int r2 = round(3.7); // r2 = 4 +float sr = sqrt(25); // sr = 5.0 + +// Vectors +// Processing provides an easy way to implement vectors in its environment using PVector class. +// It can describe a two or three dimensional vector and +// comes with a set of methods which are useful for matrices operations. +// You can find more information on PVector class and its functions here. +// (https://processing.org/reference/PVector.html) + +// Trigonometry +// Processing also supports trigonometric operations by supplying a set of functions. +// sin(), cos(), tan(), asin(), acos(), atan() and also degrees() and radians() for convenient conversion. +// However, those functions take angle in radians as the parameter so it has to be converted beforehand. +float one = sin(PI/2); // one = 1.0 +// As you may have noticed, there exists a set of constants for trigonometric uses; +// PI, HALF_PI, QUARTER_PI and so on... + +/* ------------- + Control Flow + ------------- +*/ + +// Conditional Statements +// If Statements - The same syntax as if statements in Java. +if (author.getAppearance().equals("hot")) { + print("Narcissism at its best!"); +} else { + // You can check for other conditions here. + print("Something is really wrong here!"); +} +// A shortcut for if-else statements can also be used. +int i = 3; +String value = (i > 5) ? "Big" : "Small"; // "Small" + +// Switch-case structure can be used to check multiple conditions more concisely. +int value = 2; +switch(value) { + case 0: + print("Nought!"); // This doesn't get executed. + break; // Jumps to the next statement + case 1: + print("Getting there..."); // This again doesn't get executed. + break; + case 2: + print("Bravo!"); // This line gets executed. + break; + default: + print("Not found!"); // This line gets executed if our value was some other value. + break; +} + +// Iterative statements +// For Statements - Again, the same syntax as in Java +for(int i = 0; i < 5; i ++){ + print(i); // prints from 0 to 4 +} + +// While Statements - Again, nothing new if you are familiar with Java syntax. +int j = 3; +while(j > 0) { + print(j); + j--; // This is important to prevent from the code running indefinitely. +} + +// loop()| noLoop() | redraw() | exit() +// These are more of Processing-specific functions to configure program flow. +loop(); // allows the draw() method to run forever while +noLoop(); // only allows it to run once. +redraw(); // runs the draw() method once more. +exit(); // This stops the program. It is useful for programs with draw() running continuously. +``` +## Drawing with Processing +Since you will have understood the basics of the language by now, we will now look into the best part of Processing; DRAWING. + +```processing + +/* ------ + Shapes + ------ +*/ + +// 2D Shapes + +// Point +point(x, y); // In 2D space +point(x, y, z); // In 3D space +// Draws a point in the coordinate space. + +// Line +line(x1, y1, x2, y2); // In 2D space +line(x1, y1, z1, x2, y2, z2); // In 3D space +// Draws a line connecting two points defined by (x1, y1) and (x2, y2). + +// Triangle +triangle(x1, y1, x2, y2, x3, y3); +// Draws a triangle connecting three points defined by coordinate paramters. + +// Rectangle +rect(a, b, c, d, [r]); // With optional parameter defining the radius of all corners +rect(a, b, c, d, [tl, tr, br, bl]); // With optional set of parameters defining radius of each corner +// Draws a rectangle with {a, b} as a top left coordinate and c and d as width and height respectively. + +// Quad +quad(x, y, x2, y2, x3, y3, x4, y4); +// Draws a quadrilateral with parameters defining coordinates of each corner point. + +// Ellipse +ellipse(x, y, width, height); +// Draws an eclipse at point {x, y} with width and height specified. + +// Arc +arc(x, y, width, height, start, stop, [mode]); +// While the first four parameters are self-explanatory, +// start and end defined the angles the arc starts and ends (in radians). +// Optional parameter [mode] defines the filling; +// PIE gives pie-like outline, CHORD gives the chord-like outline and OPEN is CHORD without strokes + +// Curves +// Processing provides two implementation of curves; using curve() and bezier(). +// Since I plan to keep this simple I won't be discussing any further details. +// However, if you want to implement it in your sketch, here are the references: +// (https://processing.org/reference/curve_.html)(https://processing.org/reference/bezier_.html) + +// 3D Shapes + +// 3D space can be configured by setting "P3D" to the renderer parameter in size() method. +size(width, height, P3D); +// In 3D space, you will have to translate to the particular coordinate to render the 3D shapes. + +// Box +box(size); // Cube with same length defined by size +box(w, h, d); // Box with width, height and depth separately defined + +// Sphere +sphere(radius); // Its size is defined using the radius parameter +// Mechanism behind rendering spheres is implemented by tessellating triangles. +// That said, how much detail being rendered is controlled by function sphereDetail(res) +// More information here: (https://processing.org/reference/sphereDetail_.html) + +// Irregular Shapes +// What if you wanted to draw something that's not made available by Processing's functions? +// You can use beginShape(), endShape(), vertex(x,y) to define shapes by specifying each point. +// More information here: (https://processing.org/reference/beginShape_.html) +// You can also use custom made shapes using PShape class.(https://processing.org/reference/PShape.html) + +/* --------------- + Transformations + --------------- +*/ + +// Transformations are particularly useful to keep track of the coordinate space +// and the vertices of the shapes you have drawn. +// Particularly, matrix stack methods; pushMatrix(), popMatrix() and translate(x,y) +pushMatrix(); // Saves the current coordinate system to the stack +// ... apply all the transformations here ... +popMatrix(); // Restores the saved coordinate system +// Using them, the coordinate system can be preserved and visualized without causing any conflicts. + +// Translate +translate(x, y); // Translates to point{x, y} i.e. - setting origin to that point +translate(x, y, z); // 3D counterpart of the function + +// Rotate +rotate(angle); // Rotate the amount specified by the angle parameter +// It has 3 3D counterparts to perform rotation, each for every dimension, +// namely: rotateX(angle), rotateY(angle), rotateZ(angle) + +// Scale +scale(s); // Scale the coordinate system by either expanding or contracting it. + +/* -------------------- + Styling and Textures + -------------------- +*/ + +// Colours +// As I have discussed earlier, the background colour can be configured using background() function. +// You can define a color object beforehand and then pass it to the function as an argument. +color c = color(255, 255, 255); // WHITE! +// By default, Processing uses RGB colour scheme but it can be configured to HSB using colorMode(). +// Read here: (https://processing.org/reference/colorMode_.html) +background(color); // By now, the background colour should be white. +// You can use fill() function to select the colour for filling the shapes. +// It has to be configured before you start drawing shapes so the colours gets applied. +fill(color(0, 0, 0)); +// If you just want to colour the outlines of the shapes then you can use stroke() function. +stroke(255, 255, 255, 200); // stroke colour set to yellow with transparency set to a lower value. + +// Images +// Processing can render images and use them in several ways. Mostly stored as PImage datatype. +filter(shader); // Processing supports several filter functions for image manipulation. +texture(image); // PImage can be passed into arguments for texture-mapping the shapes. + +``` +If you want to take things further, there are more things Processing is powered for. Rendering models, shaders and whatnot. +There's too much to cover in a short documentation, so I will leave them out here. Shoud you be interested, please check out the references. +```processing +// Before we move on, I will touch a little bit more on how to import libraries +// so you can extend Processing's functionality to another horizon. + +/* ------- + Imports + ------- +*/ + +// The power of Processing can be further visualized when we import libraries and packages into our sketches. +// Import statement can be written as below at the top of the source code. +import processing.something.*; + +``` +## DTC? + +Down To Code? Let's get our hands dirty! + +Let us see an example from openprocessing to visualize how much Processing is capable of within few lines of code. +Copy the code below into your Processing IDE and see the magic. + +```processing + +// Disclaimer: I did not write this program since I currently am occupied with internship and +// this sketch is adapted from openprocessing since it shows something cool with simple codes. +// Retrieved from: (https://www.openprocessing.org/sketch/559769) + +float theta; +float a; +float col; +float num; + +void setup() { + size(600,600); +} + +void draw() { + background(#F2F2F2); + translate(width/2, height/2); + theta = map(sin(millis()/1000.0), -1, 1, 0, PI/6); + + float num=6; + for (int i=0; i<num; i++) { + a =350; + rotate(TWO_PI/num); + branch(a); + } + +} + + + +void branch(float len) { + col=map(len, 0, 90, 150, 255); + fill(col, 0, 74); + stroke (col, 0, 74); + line(0, 0, 0, -len); + ellipse(0, -len, 3, 3); + len *= 0.7; + + + if (len>30) { + pushMatrix(); + translate(0, -30); + rotate(theta); + branch(len); + popMatrix(); + + pushMatrix(); + translate(0, -30); + rotate(-theta); + branch(len); + popMatrix(); + + } +} + +``` + +Processing is easy to learn and is particularly useful to create multimedia contents (even in 3D) without +having to type a lot of codes. It is so simple that you can read through the code and get a rough idea of +the program flow. +However, that does not apply when you introduce external libraries, packages and even your own classes. +(Trust me! Processing projects can get real humongous...) + +## Some useful resources: + + - [Processing Website](http://processing.org) + - [Processing Sketches](http://openprocessing.org) diff --git a/pt-br/matlab-pt.html.markdown b/pt-br/matlab-pt.html.markdown index eb660d4c..5ed6b7ba 100644 --- a/pt-br/matlab-pt.html.markdown +++ b/pt-br/matlab-pt.html.markdown @@ -206,8 +206,7 @@ size(A) % Resposta = 3 3 A(1, :) =[] % Remove a primeira linha da matriz A(:, 1) =[] % Remove a primeira coluna da matriz -transpose(A) % Transposta a matriz, que é o mesmo de: -A one +transpose(A) % Transposta a matriz, que é o mesmo de: A.' ctranspose(A) % Transposta a matriz % (a transposta, seguida pelo conjugado complexo de cada elemento) diff --git a/pythonstatcomp.html.markdown b/pythonstatcomp.html.markdown index 6dde1cf0..2440d859 100644 --- a/pythonstatcomp.html.markdown +++ b/pythonstatcomp.html.markdown @@ -38,18 +38,16 @@ r.text # raw page source print(r.text) # prettily formatted # save the page source in a file: os.getcwd() # check what's the working directory -f = open("learnxinyminutes.html", "wb") -f.write(r.text.encode("UTF-8")) -f.close() +with open("learnxinyminutes.html", "wb") as f: + f.write(r.text.encode("UTF-8")) # downloading a csv fp = "https://raw.githubusercontent.com/adambard/learnxinyminutes-docs/master/" fn = "pets.csv" r = requests.get(fp + fn) print(r.text) -f = open(fn, "wb") -f.write(r.text.encode("UTF-8")) -f.close() +with open(fn, "wb") as f: + f.write(r.text.encode("UTF-8")) """ for more on the requests module, including APIs, see http://docs.python-requests.org/en/latest/user/quickstart/ @@ -71,8 +69,8 @@ pets # 1 vesuvius 6 23 fish # 2 rex 5 34 dog -""" R users: note that Python, like most normal programming languages, starts - indexing from 0. R is the unusual one for starting from 1. +""" R users: note that Python, like most C-influenced programming languages, starts + indexing from 0. R starts indexing at 1 due to Fortran influence. """ # two different ways to print out a column @@ -205,7 +203,7 @@ hre["DeathY"] = extractYear(hre.Death) hre["EstAge"] = hre.DeathY.astype(int) - hre.BirthY.astype(int) # simple scatterplot, no trend line, color represents dynasty -sns.lmplot("BirthY", "EstAge", data=hre, hue="Dynasty", fit_reg=False); +sns.lmplot("BirthY", "EstAge", data=hre, hue="Dynasty", fit_reg=False) # use scipy to run a linear regression from scipy import stats @@ -222,7 +220,7 @@ rval**2 # 0.020363950027333586 pval # 0.34971812581498452 # use seaborn to make a scatterplot and plot the linear regression trend line -sns.lmplot("BirthY", "EstAge", data=hre); +sns.lmplot("BirthY", "EstAge", data=hre) """ For more information on seaborn, see - http://web.stanford.edu/~mwaskom/software/seaborn/ diff --git a/ro-ro/elixir-ro.html.markdown b/ro-ro/elixir-ro.html.markdown index d8b261af..10fec3c5 100644 --- a/ro-ro/elixir-ro.html.markdown +++ b/ro-ro/elixir-ro.html.markdown @@ -7,7 +7,7 @@ contributors: - ["Ev Bogdanov", "https://github.com/evbogdanov"] translators: - ["Vitalie Lazu", "https://github.com/vitaliel"] - +lang: ro-ro filename: learnelixir-ro.ex --- diff --git a/rst.html.markdown b/rst.html.markdown index 65f848ed..fbf9a069 100644 --- a/rst.html.markdown +++ b/rst.html.markdown @@ -47,9 +47,6 @@ Title are underlined with equals signs too Subtitles with dashes --------------------- -And sub-subtitles with tildes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - You can put text in *italic* or in **bold**, you can "mark" text as code with double backquote ``: ``print()``. Lists are as simple as in Markdown: diff --git a/ru-ru/clojure-ru.html.markdown b/ru-ru/clojure-ru.html.markdown index 356d1cc0..19233d23 100644 --- a/ru-ru/clojure-ru.html.markdown +++ b/ru-ru/clojure-ru.html.markdown @@ -8,9 +8,9 @@ translators: lang: ru-ru --- -Clojure, это представитель семейства Lisp-подобных языков, разработанный +Clojure — это представитель семейства Lisp-подобных языков, разработанный для Java Virtual Machine. Язык идейно гораздо ближе к чистому -[функциональному программированию](https://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) чем его прародитель Common Lisp, но в то же время обладает набором инструментов для работы с состоянием, +[функциональному программированию](https://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5), чем его прародитель Common Lisp, но в то же время обладает набором инструментов для работы с состоянием, таких как [STM](https://ru.wikipedia.org/wiki/Software_transactional_memory). Благодаря такому сочетанию технологий в одном языке, разработка программ, @@ -23,9 +23,9 @@ Clojure, это представитель семейства Lisp-подобн ```clojure ; Комментарии начинаются символом ";". -; Код на языке Clojure записывается в виде "форм", +; Код на языке Clojure записывается в виде «форм», ; которые представляют собой обычные списки элементов, разделенных пробелами, -; заключённые в круглые скобки +; заключённые в круглые скобки. ; ; Clojure Reader (инструмент языка, отвечающий за чтение исходного кода), ; анализируя форму, предполагает, что первым элементом формы (т.е. списка) @@ -76,32 +76,32 @@ Clojure, это представитель семейства Lisp-подобн '(+ 1 2) ; => (+ 1 2) ; ("'", это краткая запись формы (quote (+ 1 2)) -; "Квотированный" список можно вычислить, передав его функции eval +; «Квотированный» список можно вычислить, передав его функции eval (eval '(+ 1 2)) ; => 3 ; Коллекции и Последовательности ;;;;;;;;;;;;;;;;;;; -; Списки (Lists) в clojure структурно представляют собой "связанные списки", +; Списки (Lists) в clojure структурно представляют собой «связанные списки», ; тогда как Векторы (Vectors), устроены как массивы. ; Векторы и Списки тоже являются классами Java! (class [1 2 3]); => clojure.lang.PersistentVector (class '(1 2 3)); => clojure.lang.PersistentList -; Список может быть записан, как (1 2 3), но в этом случае +; Список может быть записан как (1 2 3), но в этом случае ; он будет воспринят reader`ом, как вызов функции. ; Есть два способа этого избежать: ; '(1 2 3) - квотирование, ; (list 1 2 3) - явное конструирование списка с помощью функции list. -; "Коллекции", это некие наборы данных +; «Коллекции» — это некие наборы данных. ; И списки, и векторы являются коллекциями: (coll? '(1 2 3)) ; => true (coll? [1 2 3]) ; => true -; "Последовательности" (seqs), это абстракция над наборами данных, +; «Последовательности» (seqs) — это абстракция над наборами данных, ; элементы которых "упакованы" последовательно. -; Списки - последовательности, а вектора - нет. +; Списки — последовательности, а векторы — нет. (seq? '(1 2 3)) ; => true (seq? [1 2 3]) ; => false @@ -119,7 +119,7 @@ Clojure, это представитель семейства Lisp-подобн ; Функция conj добавляет элемент в коллекцию ; максимально эффективным для неё способом. -; Для списков эффективно добавление в начло, а для векторов - в конец. +; Для списков эффективно добавление в начло, а для векторов — в конец. (conj [1 2 3] 4) ; => [1 2 3 4] (conj '(1 2 3) 4) ; => (4 1 2 3) @@ -130,7 +130,7 @@ Clojure, это представитель семейства Lisp-подобн (map inc [1 2 3]) ; => (2 3 4) (filter even? [1 2 3]) ; => (2) -; reduce поможет "свернуть" коллекцию +; reduce поможет «свернуть» коллекцию (reduce + [1 2 3 4]) ; = (+ (+ (+ 1 2) 3) 4) ; => 10 @@ -144,12 +144,12 @@ Clojure, это представитель семейства Lisp-подобн ;;;;;;;;;;;;;;;;;;;;; ; Функция создается специальной формой fn. -; "Тело" функции может состоять из нескольких форм, +; «Тело» функции может состоять из нескольких форм, ; но результатом вызова функции всегда будет результат вычисления ; последней из них. (fn [] "Hello World") ; => fn -; (Вызов функции требует "оборачивания" fn-формы в форму вызова) +; (Вызов функции требует «оборачивания» fn-формы в форму вызова) ((fn [] "Hello World")) ; => "Hello World" ; Назначить значению имя можно специальной формой def @@ -160,7 +160,7 @@ x ; => 1 (def hello-world (fn [] "Hello World")) (hello-world) ; => "Hello World" -; Поскольку именование функций - очень частая операция, +; Поскольку именование функций — очень частая операция, ; clojure позволяет, сделать это проще: (defn hello-world [] "Hello World") @@ -211,7 +211,7 @@ x ; => 1 ; Отображения могут использовать в качестве ключей любые хэшируемые значения, ; однако предпочтительными являются ключи, -; являющиеся "ключевыми словами" (keywords) +; являющиеся «ключевыми словами» (keywords) (class :a) ; => clojure.lang.Keyword (def stringmap {"a" 1, "b" 2, "c" 3}) @@ -263,7 +263,7 @@ keymap ; => {:a 1, :b 2, :c 3} - оригинал не был затронут ; Исключаются - посредством disj (disj #{1 2 3} 1) ; => #{2 3} -; Вызов множества, как функции, позволяет проверить +; Вызов множества как функции позволяет проверить ; принадлежность элемента этому множеству: (#{1 2 3} 1) ; => 1 (#{1 2 3} 4) ; => nil @@ -274,8 +274,8 @@ keymap ; => {:a 1, :b 2, :c 3} - оригинал не был затронут ; Полезные формы ;;;;;;;;;;;;;;;;; -; Конструкции ветвления в clojure, это обычные макросы -; и подобны их собратьям в других языках: +; Конструкции ветвления в clojure — это обычные макросы, +; они подобны своим собратьям в других языках: (if false "a" "b") ; => "b" (if false "a") ; => nil @@ -285,7 +285,7 @@ keymap ; => {:a 1, :b 2, :c 3} - оригинал не был затронут (let [a 1 b 2] (> a b)) ; => false -; Несколько форм можно объединить в одну форму посредством do +; Несколько форм можно объединить в одну форму посредством do. ; Значением do-формы будет значение последней формы из списка вложенных в неё: (do (print "Hello") @@ -298,7 +298,7 @@ keymap ; => {:a 1, :b 2, :c 3} - оригинал не был затронут (str "Hello " name)) (print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff") -; Ещё один пример - let: +; Ещё один пример — let: (let [name "Urkel"] (print "Saying hello to " name) (str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel") @@ -306,7 +306,7 @@ keymap ; => {:a 1, :b 2, :c 3} - оригинал не был затронут ; Модули ;;;;;;;;; -; Форма "use" позволяет добавить в текущее пространство имен +; Форма use позволяет добавить в текущее пространство имен ; все имена (вместе со значениями) из указанного модуля: (use 'clojure.set) @@ -392,7 +392,7 @@ keymap ; => {:a 1, :b 2, :c 3} - оригинал не был затронут my-atom ;=> Atom<#...> (Возвращает объект типа Atom) @my-atom ; => {:a 1 :b 2} -; Пример реализации счётчика на атоме +; Пример реализации счётчика на атоме: (def counter (atom 0)) (defn inc-counter [] (swap! counter inc)) @@ -414,13 +414,13 @@ my-atom ;=> Atom<#...> (Возвращает объект типа Atom) Это руководство не претендует на полноту, но мы смеем надеяться, способно вызвать интерес к дальнейшему изучению языка. -Clojure.org - сайт содержит большое количество статей по языку: +Сайт Clojure.org содержит большое количество статей по языку: [http://clojure.org/](http://clojure.org/) -Clojuredocs.org - сайт документации языка с примерами использования функций: +Clojuredocs.org — сайт документации языка с примерами использования функций: [http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core) -4Clojure - отличный способ закрепить навыки программирования на clojure, решая задачи вместе с коллегами со всего мира: +4Clojure — отличный способ закрепить навыки программирования на clojure, решая задачи вместе с коллегами со всего мира: [http://www.4clojure.com/](http://www.4clojure.com/) Clojure-doc.org (да, именно) неплохой перечень статей для начинающих: diff --git a/ru-ru/jquery-ru.html.markdown b/ru-ru/jquery-ru.html.markdown new file mode 100644 index 00000000..471b4e24 --- /dev/null +++ b/ru-ru/jquery-ru.html.markdown @@ -0,0 +1,127 @@ +--- +category: tool +tool: jquery +contributors: + - ["Sawyer Charles", "https://github.com/xssc"] +translators: + - ["Ev Bogdanov", "https://github.com/evbogdanov"] +lang: ru-ru +filename: jquery-ru.js +--- + +jQuery — это библиотека JavaScript, которая помогает "делать больше, писать меньше". Она выполняет множество типичных JavaScript-задач, упрощая написание кода. jQuery используется крупными компаниями и разработчиками со всего мира. Она упрощает и ускоряет работу с AJAX, с событиями, с DOM и со многим другим. + +Поскольку jQuery является библиотекой JavaScript, вам следует начать с [изучения JavaScript](https://learnxinyminutes.com/docs/ru-ru/javascript-ru/). + +```js + + +/////////////////////////////////// +// 1. Селекторы + +// Для получения элемента в jQuery используются селекторы +var page = $(window); // Получить страницу целиком + +// В качестве селектора может выступать CSS-селектор +var paragraph = $('p'); // Получить все <p> элементы +var table1 = $('#table1'); // Получить элемент с идентификатором 'table1' +var squares = $('.square'); // Получить все элементы с классом 'square' +var square_p = $('p.square') // Получить <p> элементы с классом 'square' + + +/////////////////////////////////// +// 2. События и эффекты +// jQuery прекрасно справляется с обработкой событий +// Часто используемое событие — это событие документа 'ready' +// Вы можете использовать метод 'ready', который сработает, как только документ полностью загрузится +$(document).ready(function(){ + // Код не выполнится до тех пор, пока документ не будет загружен +}); +// Обработку события можно вынести в отдельную функцию +function onAction() { + // Код выполнится, когда произойдёт событие +} +$('#btn').click(onAction); // Обработчик события сработает при клике + +// Другие распространённые события: +$('#btn').dblclick(onAction); // Двойной клик +$('#btn').hover(onAction); // Наведение курсора +$('#btn').focus(onAction); // Фокус +$('#btn').blur(onAction); // Потеря фокуса +$('#btn').submit(onAction); // Отправка формы +$('#btn').select(onAction); // Когда выбрали элемент +$('#btn').keydown(onAction); // Когда нажали клавишу +$('#btn').keyup(onAction); // Когда отпустили клавишу +$('#btn').keypress(onAction); // Когда нажали символьную клавишу (нажатие привело к появлению символа) +$('#btn').mousemove(onAction); // Когда переместили курсор мыши +$('#btn').mouseenter(onAction); // Когда навели курсор на элемент +$('#btn').mouseleave(onAction); // Когда сдвинули курсор с элемента + + +// Вы можете не только обрабатывать события, но и вызывать их +$('#btn').dblclick(); // Вызвать двойной клик на элементе + +// Для одного селектора возможно назначить несколько обработчиков событий +$('#btn').on( + {dblclick: myFunction1} // Обработать двойной клик + {blur: myFunction1} // Обработать исчезновение фокуса +); + +// Вы можете перемещать и прятать элементы с помощью методов-эффектов +$('.table').hide(); // Спрятать элемент(ы) + +// Обратите внимание: вызов функции в этих методах всё равно спрячет сам элемент +$('.table').hide(function(){ + // Сначала спрятать элемент, затем вызвать функцию +}); + +// Вы можете хранить селекторы в переменных +var tables = $('.table'); + +// Некоторые основные методы для манипуляций с документом: +tables.hide(); // Спрятать элемент(ы) +tables.show(); // Показать элемент(ы) +tables.toggle(); // Спрятать/показать +tables.fadeOut(); // Плавное исчезновение +tables.fadeIn(); // Плавное появление +tables.fadeToggle(); // Плавное исчезновение или появление +tables.fadeTo(0.5); // Изменение прозрачности +tables.slideUp(); // Свернуть элемент +tables.slideDown(); // Развернуть элемент +tables.slideToggle(); // Свернуть или развернуть + +// Все эти методы принимают скорость (в миллисекундах) и функцию обратного вызова +tables.hide(1000, myFunction); // Анимация длится 1 секунду, затем вызов функции + +// В методе 'fadeTo' вторым параметром обязательно идёт прозрачность +tables.fadeTo(2000, 0.1, myFunction); // Прозрачность меняется в течение 2 секунд до 0.1, затем вызывается функция + +// Метод 'animate' позволяет делать более продвинутую анимацию +tables.animate({"margin-top": "+=50", height: "100px"}, 500, myFunction); + + +/////////////////////////////////// +// 3. Манипуляции + +// Манипуляции похожи на эффекты, но позволяют добиться большего +$('div').addClass('taming-slim-20'); // Добавить класс 'taming-slim-20' ко всем <div> элементам + +// Часто встречающиеся методы манипуляций +$('p').append('Hello world'); // Добавить в конец элемента +$('p').attr('class'); // Получить атрибут +$('p').attr('class', 'content'); // Установить атрибут +$('p').hasClass('taming-slim-20'); // Проверить наличие класса +$('p').height(); // Получить или установить высоту элемента + + +// Во многих методах вам доступна информация ТОЛЬКО о первом элементе из выбранных +$('p').height(); // Вы получите высоту только для первого <p> элемента + +// Метод 'each' позволяет это исправить и пройтись по всем выбранным вами элементам +var heights = []; +$('p').each(function() { + heights.push($(this).height()); // Добавить высоту всех <p> элементов в массив +}); + + +``` diff --git a/ruby-ecosystem.html.markdown b/ruby-ecosystem.html.markdown index 50eedcd0..3c80075b 100644 --- a/ruby-ecosystem.html.markdown +++ b/ruby-ecosystem.html.markdown @@ -10,6 +10,16 @@ contributors: People using Ruby generally have a way to install different Ruby versions, manage their packages (or gems), and manage their gem dependencies. +## Ruby Versions + +Ruby was created by Yukihiro "Matz" Matsumoto, who remains somewhat of a +[BDFL](https://en.wikipedia.org/wiki/Benevolent_Dictator_for_Life), although +that is changing recently. As a result, the reference implementation of Ruby is +called MRI (Matz' Reference Implementation), and when you hear a Ruby version, +it is referring to the release version of MRI. + +New major versions of Ruby are traditionally released on Christmas Day. The current major version (25 December 2017) is 2.5. The most popular stable versions are 2.4.4 and 2.3.7 (both released 28 March 2018). + ## Ruby Managers Some platforms have Ruby pre-installed or available as a package. Most rubyists @@ -29,28 +39,6 @@ The following are the popular Ruby environment managers: * [chruby](https://github.com/postmodern/chruby) - Only switches between rubies. Similar in spirit to rbenv. Unopinionated about how rubies are installed. -## Ruby Versions - -Ruby was created by Yukihiro "Matz" Matsumoto, who remains somewhat of a -[BDFL](https://en.wikipedia.org/wiki/Benevolent_Dictator_for_Life), although -that is changing recently. As a result, the reference implementation of Ruby is -called MRI (Matz' Reference Implementation), and when you hear a Ruby version, -it is referring to the release version of MRI. - -The three major version of Ruby in use are: - -* 2.0.0 - Released in February 2013. Most major libraries and frameworks support - 2.0.0. -* 1.9.3 - Released in October 2011. This is the version most rubyists use - currently. Also [retired](https://www.ruby-lang.org/en/news/2015/02/23/support-for-ruby-1-9-3-has-ended/) -* 1.8.7 - Ruby 1.8.7 has been - [retired](http://www.ruby-lang.org/en/news/2013/06/30/we-retire-1-8-7/). - -The change between 1.8.7 to 1.9.x is a much larger change than 1.9.3 to 2.0.0. -For instance, the 1.9 series introduced encodings and a bytecode VM. There -are projects still on 1.8.7, but they are becoming a small minority, as most of -the community has moved to at least 1.9.2 or 1.9.3. - ## Ruby Implementations The Ruby ecosystem enjoys many different implementations of Ruby, each with diff --git a/scala.html.markdown b/scala.html.markdown index 016e2b4f..28424684 100644 --- a/scala.html.markdown +++ b/scala.html.markdown @@ -716,7 +716,7 @@ import scala.collection.immutable.{Map => _, Set => _, _} // Java classes can also be imported. Scala syntax can be used import java.swing.{JFrame, JWindow} -// Your programs entry point is defined in an scala file using an object, with a +// Your programs entry point is defined in a scala file using an object, with a // single method, main: object Application { def main(args: Array[String]): Unit = { diff --git a/solidity.html.markdown b/solidity.html.markdown index b657b6a1..004c225e 100644 --- a/solidity.html.markdown +++ b/solidity.html.markdown @@ -829,7 +829,6 @@ someContractAddress.callcode('function_name'); ## Additional resources - [Solidity Docs](https://solidity.readthedocs.org/en/latest/) - [Smart Contract Best Practices](https://github.com/ConsenSys/smart-contract-best-practices) -- [Solidity Style Guide](https://ethereum.github.io/solidity//docs/style-guide/): Ethereum's style guide is heavily derived from Python's [pep8](https://www.python.org/dev/peps/pep-0008/) style guide. - [EthFiddle - The JsFiddle for Solidity](https://ethfiddle.com/) - [Browser-based Solidity Editor](https://remix.ethereum.org/) - [Gitter Solidity Chat room](https://gitter.im/ethereum/solidity) @@ -850,9 +849,10 @@ someContractAddress.callcode('function_name'); - [Hacking Distributed Blog](http://hackingdistributed.com/) ## Style -- Python's [PEP8](https://www.python.org/dev/peps/pep-0008/) is used as the baseline style guide, including its general philosophy +- [Solidity Style Guide](http://solidity.readthedocs.io/en/latest/style-guide.html): Ethereum's style guide is heavily derived from Python's [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guide. ## Editors +- [Emacs Solidity Mode](https://github.com/ethereum/emacs-solidity) - [Vim Solidity](https://github.com/tomlion/vim-solidity) - Editor Snippets ([Ultisnips format](https://gist.github.com/nemild/98343ce6b16b747788bc)) diff --git a/zh-cn/c-cn.html.markdown b/zh-cn/c-cn.html.markdown index 02ec7f7b..8566e811 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/julia-cn.html.markdown b/zh-cn/julia-cn.html.markdown index 1f91d52c..b350b6dc 100644 --- a/zh-cn/julia-cn.html.markdown +++ b/zh-cn/julia-cn.html.markdown @@ -2,16 +2,24 @@ language: Julia filename: learn-julia-zh.jl contributors: - - ["Jichao Ouyang", "http://oyanglul.us"] + - ["Leah Hanson", "http://leahhanson.us"] + - ["Pranit Bauva", "https://github.com/pranitbauva1997"] + - ["Daniel YC Lin", "https://github.com/dlintw"] translators: - ["Jichao Ouyang", "http://oyanglul.us"] + - ["woclass", "https://github.com/inkydragon"] lang: zh-cn --- -```ruby -# 单行注释只需要一个井号 +Julia 是一种新的同像函数式编程语言(homoiconic functional language),它专注于科学计算领域。 +虽然拥有同像宏(homoiconic macros)、一级函数(first-class functions)和底层控制等全部功能,但 Julia 依旧和 Python 一样易于学习和使用。 + +示例代码基于 Julia 1.0.0 + +```julia +# 单行注释只需要一个井号「#」 #= 多行注释 - 只需要以 '#=' 开始 '=#' 结束 + 只需要以「#=」开始「=#」结束 还可以嵌套. =# @@ -19,41 +27,41 @@ lang: zh-cn ## 1. 原始类型与操作符 #################################################### -# Julia 中一切皆是表达式。 - -# 这是一些基本数字类型. -3 # => 3 (Int64) -3.2 # => 3.2 (Float64) -2 + 1im # => 2 + 1im (Complex{Int64}) -2//3 # => 2//3 (Rational{Int64}) - -# 支持所有的普通中缀操作符。 -1 + 1 # => 2 -8 - 1 # => 7 -10 * 2 # => 20 -35 / 5 # => 7.0 -5 / 2 # => 2.5 # 用 Int 除 Int 永远返回 Float -div(5, 2) # => 2 # 使用 div 截断小数点 -5 \ 35 # => 7.0 -2 ^ 2 # => 4 # 次方, 不是二进制 xor -12 % 10 # => 2 +# Julia 中一切皆为表达式 + +# 这是一些基本数字类型 +typeof(3) # => Int64 +typeof(3.2) # => Float64 +typeof(2 + 1im) # => Complex{Int64} +typeof(2 // 3) # => Rational{Int64} + +# 支持所有的普通中缀操作符 +1 + 1 # => 2 +8 - 1 # => 7 +10 * 2 # => 20 +35 / 5 # => 7.0 +10 / 2 # => 5.0 # 整数除法总是返回浮点数 +div(5, 2) # => 2 # 使用 div 可以获得整除的结果 +5 \ 35 # => 7.0 +2^2 # => 4 # 幂运算,不是异或 (xor) +12 % 10 # => 2 # 用括号提高优先级 (1 + 3) * 2 # => 8 -# 二进制操作符 -~2 # => -3 # 非 -3 & 5 # => 1 # 与 -2 | 4 # => 6 # 或 -2 $ 4 # => 6 # 异或 -2 >>> 1 # => 1 # 逻辑右移 -2 >> 1 # => 1 # 算术右移 -2 << 1 # => 4 # 逻辑/算术 右移 - -# 可以用函数 bits 查看二进制数。 -bits(12345) +# 位操作符 +~2 # => -3 # 按位非 (not) +3 & 5 # => 1 # 按位与 (and) +2 | 4 # => 6 # 按位或 (or) +xor(2, 4) # => 6 # 按位异或 (xor) +2 >>> 1 # => 1 # 逻辑右移 +2 >> 1 # => 1 # 算术右移 +2 << 1 # => 4 # 逻辑/算术左移 + +# 可以用函数 bitstring 查看二进制数。 +bitstring(12345) # => "0000000000000000000000000000000000000000000000000011000000111001" -bits(12345.0) +bitstring(12345.0) # => "0100000011001000000111001000000000000000000000000000000000000000" # 布尔值是原始类型 @@ -61,40 +69,50 @@ true false # 布尔操作符 -!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 + +# 链式比较 1 < 2 < 3 # => true 2 < 3 < 2 # => false -# 字符串可以由 " 创建 +# 字符串可以由「"」创建 "This is a string." -# 字符字面量可用 ' 创建 +# 字符字面量可用「'」创建 'a' +# 字符串使用 UTF-8 编码 # 可以像取数组取值一样用 index 取出对应字符 -"This is a string"[1] # => 'T' # Julia 的 index 从 1 开始 :( -# 但是对 UTF-8 无效, -# 因此建议使用遍历器 (map, for loops, 等). +ascii("This is a string")[1] +# => 'T': ASCII/Unicode U+0054 (category Lu: Letter, uppercase) +# Julia 的 index 从 1 开始 :( +# 但只有在字符串仅由 ASCII 字符构成时,字符串才能够被安全的引索 +# 因此建议使用遍历器 (map, for loops, 等) # $ 可用于字符插值: "2 + 2 = $(2 + 2)" # => "2 + 2 = 4" # 可以将任何 Julia 表达式放入括号。 -# 另一种格式化字符串的方式是 printf 宏. -@printf "%d is less than %f" 4.5 5.3 # 5 is less than 5.300000 +# 另一种输出格式化字符串的方法是使用标准库 Printf 中的 Printf 宏 +using Printf +@printf "%d is less than %f\n" 4.5 5.3 # => 5 is less than 5.300000 # 打印字符串很容易 -println("I'm Julia. Nice to meet you!") +println("I'm Julia. Nice to meet you!") # => I'm Julia. Nice to meet you! + +# 字符串可以按字典序进行比较 +"good" > "bye" # => true +"good" == "good" # => true +"1 + 2 = 3" == "1 + 2 = $(1 + 2)" # => true #################################################### ## 2. 变量与集合 @@ -106,12 +124,12 @@ some_var # => 5 # 访问未声明变量会抛出异常 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 -# 变量名需要以字母开头. +# 变量名必须以下划线或字母开头 # 之后任何字母,数字,下划线,叹号都是合法的。 SomeOtherVar123! = 6 # => 6 @@ -122,66 +140,93 @@ SomeOtherVar123! = 6 # => 6 # 注意 Julia 的命名规约: # -# * 变量名为小写,单词之间以下划线连接('\_')。 +# * 名称可以用下划线「_」分割。 +# 不过一般不推荐使用下划线,除非不用变量名就会变得难于理解 # -# * 类型名以大写字母开头,单词以 CamelCase 方式连接。 +# * 类型名以大写字母开头,单词以 CamelCase 方式连接,无下划线。 # # * 函数与宏的名字小写,无下划线。 # -# * 会改变输入的函数名末位为 !。 +# * 会改变输入的函数名末位为「!」。 # 这类函数有时被称为 mutating functions 或 in-place functions. -# 数组存储一列值,index 从 1 开始。 -a = Int64[] # => 0-element Int64 Array +# 数组存储一列值,index 从 1 开始 +a = Int64[] # => 0-element Array{Int64,1} + +# 一维数组可以以逗号分隔值的方式声明 +b = [4, 5, 6] # => 3-element Array{Int64,1}: [4, 5, 6] +b = [4; 5; 6] # => 3-element Array{Int64,1}: [4, 5, 6] +b[1] # => 4 +b[end] # => 6 -# 一维数组可以以逗号分隔值的方式声明。 -b = [4, 5, 6] # => 包含 3 个 Int64 类型元素的数组: [4, 5, 6] -b[1] # => 4 -b[end] # => 6 +# 二维数组以分号分隔维度 +matrix = [1 2; 3 4] # => 2×2 Array{Int64,2}: [1 2; 3 4] -# 二维数组以分号分隔维度。 -matrix = [1 2; 3 4] # => 2x2 Int64 数组: [1 2; 3 4] +# 指定数组的类型 +b = Int8[4, 5, 6] # => 3-element Array{Int8,1}: [4, 5, 6] # 使用 push! 和 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] -# 用 pop 弹出末尾元素 -pop!(b) # => 6 and b is now [4,5] +# 用 pop 弹出尾部的元素 +pop!(b) # => 6 +b # => [4,5] -# 可以再放回去 -push!(b,6) # b 又变成了 [4,5,6]. +# 再放回去 +push!(b, 6) # => [4,5,6] +b # => [4,5,6] -a[1] # => 1 # 永远记住 Julia 的 index 从 1 开始! +a[1] # => 1 # 永远记住 Julia 的引索从 1 开始!而不是 0! -# 用 end 可以直接取到最后索引. 可用作任何索引表达式 +# 用 end 可以直接取到最后索引。它可以用在任何索引表达式中 a[end] # => 6 -# 还支持 shift 和 unshift -shift!(a) # => 返回 1,而 a 现在时 [2,4,3,4,5,6] -unshift!(a,7) # => [7,2,4,3,4,5,6] +# 数组还支持 popfirst! 和 pushfirst! +popfirst!(a) # => 1 +a # => [2,4,3,4,5,6] +pushfirst!(a, 7) # => [7,2,4,3,4,5,6] +a # => [7,2,4,3,4,5,6] # 以叹号结尾的函数名表示它会改变参数的值 -arr = [5,4,6] # => 包含三个 Int64 元素的数组: [5,4,6] -sort(arr) # => [4,5,6]; arr 还是 [5,4,6] -sort!(arr) # => [4,5,6]; arr 现在是 [4,5,6] +arr = [5,4,6] # => 3-element Array{Int64,1}: [5,4,6] +sort(arr) # => [4,5,6] +arr # => [5,4,6] +sort!(arr) # => [4,5,6] +arr # => [4,5,6] -# 越界会抛出 BoundsError 异常 +# 数组越界会抛出 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] + # => ERROR: BoundsError: attempt to access 7-element Array{Int64,1} at + # index [0] + # => Stacktrace: + # => [1] getindex(::Array{Int64,1}, ::Int64) at .\array.jl:731 + # => [2] top-level scope at none:0 + # => [3] ... + # => in expression starting at ...\LearnJulia.jl:203 + a[end + 1] + # => ERROR: BoundsError: attempt to access 7-element Array{Int64,1} at + # index [8] + # => Stacktrace: + # => [1] getindex(::Array{Int64,1}, ::Int64) at .\array.jl:731 + # => [2] top-level scope at none:0 + # => [3] ... + # => in expression starting at ...\LearnJulia.jl:211 catch e println(e) end -# 错误会指出发生的行号,包括标准库 -# 如果你有 Julia 源代码,你可以找到这些地方 +# 报错时错误会指出出错的文件位置以及行号,标准库也一样 +# 你可以在 Julia 安装目录下的 share/julia 文件夹里找到这些标准库 # 可以用 range 初始化数组 -a = [1:5] # => 5-element Int64 Array: [1,2,3,4,5] +a = [1:5;] # => 5-element Array{Int64,1}: [1,2,3,4,5] +# 注意!分号不可省略 +a2 = [1:5] # => 1-element Array{UnitRange{Int64},1}: [1:5] # 可以切割数组 a[1:3] # => [1, 2, 3] @@ -189,11 +234,13 @@ a[2:end] # => [2, 3, 4, 5] # 用 splice! 切割原数组 arr = [3,4,5] -splice!(arr,2) # => 4 ; arr 变成了 [3,5] +splice!(arr, 2) # => 4 +arr # => [3,5] # 用 append! 连接数组 b = [1,2,3] -append!(a,b) # a 变成了 [1, 2, 3, 4, 5, 1, 2, 3] +append!(a, b) # => [1, 2, 3, 4, 5, 1, 2, 3] +a # => [1, 2, 3, 4, 5, 1, 2, 3] # 检查元素是否在数组中 in(1, a) # => true @@ -201,240 +248,258 @@ in(1, a) # => true # 用 length 获得数组长度 length(a) # => 8 -# Tuples 是 immutable 的 -tup = (1, 2, 3) # => (1,2,3) # an (Int64,Int64,Int64) tuple. +# 元组(Tuples)是不可变的 +tup = (1, 2, 3) # => (1,2,3) +typeof(tup) # => Tuple{Int64,Int64,Int64} tup[1] # => 1 -try: - tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64) +try + tup[1] = 3 + # => ERROR: MethodError: no method matching + # setindex!(::Tuple{Int64,Int64,Int64}, ::Int64, ::Int64) catch e println(e) end -# 大多数组的函数同样支持 tuples +# 大多数组的函数同样支持元组 length(tup) # => 3 -tup[1:2] # => (1,2) -in(2, tup) # => true +tup[1:2] # => (1,2) +in(2, tup) # => true -# 可以将 tuples 元素分别赋给变量 -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 # => 1 +b # => 2 +c # => 3 # 不用括号也可以 -d, e, f = 4, 5, 6 # => (4,5,6) +d, e, f = 4, 5, 6 # => (4,5,6) +d # => 4 +e # => 5 +f # => 6 # 单元素 tuple 不等于其元素值 (1,) == 1 # => false -(1) == 1 # => true +(1) == 1 # => true # 交换值 -e, d = d, e # => (5,4) # d is now 5 and e is now 4 +e, d = d, e # => (5,4) +d # => 5 +e # => 4 -# 字典Dictionaries store mappings -empty_dict = Dict() # => Dict{Any,Any}() +# 字典用于储存映射(mappings)(键值对) +empty_dict = Dict() # => Dict{Any,Any} with 0 entries # 也可以用字面量创建字典 -filled_dict = ["one"=> 1, "two"=> 2, "three"=> 3] -# => Dict{ASCIIString,Int64} +filled_dict = Dict("one" => 1, "two" => 2, "three" => 3) +# => Dict{String,Int64} with 3 entries: +# => "two" => 2, "one" => 1, "three" => 3 # 用 [] 获得键值 filled_dict["one"] # => 1 # 获得所有键 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" # 注意,键的顺序不是插入时的顺序 # 获得所有值 values(filled_dict) -# => ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2]) +# => Base.ValueIterator for a Dict{String,Int64} with 3 entries. Values: +# => 2, 1, 3 # 注意,值的顺序也一样 # 用 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 # 获取不存在的键的值会抛出异常 try - filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489 + filled_dict["four"] # => ERROR: KeyError: key "four" not found catch e println(e) end # 使用 get 可以提供默认值来避免异常 # get(dictionary,key,default_value) -get(filled_dict,"one",4) # => 1 -get(filled_dict,"four",4) # => 4 +get(filled_dict, "one", 4) # => 1 +get(filled_dict, "four", 4) # => 4 -# 用 Sets 表示无序不可重复的值的集合 -empty_set = Set() # => Set{Any}() -# 初始化一个 Set 并定义其值 -filled_set = Set(1,2,2,3,4) # => Set{Int64}(1,2,3,4) +# Set 表示无序不可重复的值的集合 +empty_set = Set() # => Set(Any[]) +# 初始化一个带初值的 Set +filled_set = Set([1, 2, 2, 3, 4]) # => Set([4, 2, 3, 1]) -# 添加值 -push!(filled_set,5) # => Set{Int64}(5,4,2,3,1) +# 新增值 +push!(filled_set, 5) # => Set([4, 2, 3, 5, 1]) -# 检查是否存在某值 -in(2, filled_set) # => true -in(10, filled_set) # => false +# 检查 Set 中是否存在某值 +in(2, filled_set) # => true +in(10, filled_set) # => false # 交集,并集,差集 -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]) #################################################### -## 3. 控制流 +## 3. 控制语句 #################################################### # 声明一个变量 some_var = 5 -# 这是一个 if 语句,缩进不是必要的 +# 这是一个 if 语句块,其中的缩进不是必须的 if some_var > 10 println("some_var is totally bigger than 10.") -elseif some_var < 10 # elseif 是可选的. +elseif some_var < 10 # elseif 是可选的 println("some_var is smaller than 10.") -else # else 也是可选的. +else # else 也是可选的 println("some_var is indeed 10.") end -# => prints "some var is smaller than 10" +# => some_var is smaller than 10. # For 循环遍历 -# Iterable 类型包括 Range, Array, Set, Dict, 以及 String. -for animal=["dog", "cat", "mouse"] +# 可迭代的类型包括:Range, Array, Set, Dict 和 AbstractString +for animal = ["dog", "cat", "mouse"] println("$animal is a mammal") - # 可用 $ 将 variables 或 expression 转换为字符串into strings + # 你可以用 $ 将变量或表达式插入字符串中 end -# prints: -# dog is a mammal -# cat is a mammal -# mouse is a mammal +# => dog is a mammal +# => cat is a mammal +# => mouse is a mammal -# You can use 'in' instead of '='. +# 你也可以不用「=」而使用「in」 for animal in ["dog", "cat", "mouse"] println("$animal is a mammal") end -# prints: -# dog is a mammal -# cat is a mammal -# mouse is a mammal +# => dog is a mammal +# => cat is a mammal +# => mouse is a mammal -for a in ["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 +# => mouse is a mammal +# => cat is a mammal +# => dog is a mammal +# 注意!这里的输出顺序和上面的不同 -for (k,v) in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"] +for (k, v) in Dict("dog" => "mammal", "cat" => "mammal", "mouse" => "mammal") println("$k is a $v") end -# prints: -# dog is a mammal -# cat is a mammal -# mouse is a mammal +# => mouse is a mammal +# => cat is a mammal +# => dog is a mammal # While 循环 -x = 0 -while x < 4 - println(x) - x += 1 # x = x + 1 +let x = 0 + while x < 4 + println(x) + x += 1 # x = x + 1 的缩写 + end end -# prints: -# 0 -# 1 -# 2 -# 3 +# => 0 +# => 1 +# => 2 +# => 3 # 用 try/catch 处理异常 try - error("help") + error("help") catch e - println("caught it $e") + println("caught it $e") end # => caught it ErrorException("help") - #################################################### ## 4. 函数 #################################################### -# 用关键字 'function' 可创建一个新函数 -#function name(arglist) -# body... -#end +# 关键字 function 用于定义函数 +# function name(arglist) +# body... +# end function add(x, y) println("x is $x and y is $y") - # 最后一行语句的值为返回 + # 函数会返回最后一行的值 x + y end -add(5, 6) # => 在 "x is 5 and y is 6" 后会打印 11 +add(5, 6) +# => x is 5 and y is 6 +# => 11 + +# 更紧凑的定义函数 +f_add(x, y) = x + y # => f_add (generic function with 1 method) +f_add(3, 4) # => 7 + +# 函数可以将多个值作为元组返回 +fn(x, y) = x + y, x - y # => fn (generic function with 1 method) +fn(3, 4) # => (7, -1) # 还可以定义接收可变长参数的函数 function varargs(args...) return args - # 关键字 return 可在函数内部任何地方返回 + # 使用 return 可以在函数内的任何地方返回 end # => varargs (generic function with 1 method) varargs(1,2,3) # => (1,2,3) -# 省略号 ... 被称为 splat. +# 省略号「...」称为 splat # 刚刚用在了函数定义中 -# 还可以用在函数的调用 -# Array 或者 Tuple 的内容会变成参数列表 -Set([1,2,3]) # => Set{Array{Int64,1}}([1,2,3]) # 获得一个 Array 的 Set -Set([1,2,3]...) # => Set{Int64}(1,2,3) # 相当于 Set(1,2,3) +# 在调用函数时也可以使用它,此时它会把数组或元组解包为参数列表 +add([5,6]...) # 等价于 add(5,6) -x = (1,2,3) # => (1,2,3) -Set(x) # => Set{(Int64,Int64,Int64)}((1,2,3)) # 一个 Tuple 的 Set -Set(x...) # => Set{Int64}(2,3,1) +x = (5, 6) # => (5,6) +add(x...) # 等价于 add(5,6) - -# 可定义可选参数的函数 -function defaults(a,b,x=5,y=6) +# 可定义带可选参数的函数 +function defaults(a, b, x=5, y=6) return "$a $b and $x $y" end +# => defaults (generic function with 3 methods) -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: MethodError: no method matching defaults(::Char) + defaults() # => ERROR: MethodError: no method matching defaults() catch e println(e) end -# 还可以定义键值对的参数 -function keyword_args(;k1=4,name2="hello") # note the ; - return ["k1"=>k1,"name2"=>name2] +# 还可以定义带关键字参数的函数 +function keyword_args(;k1=4, name2="hello") # 注意分号 ';' + return Dict("k1" => k1, "name2" => name2) end +# => keyword_args (generic function with 1 method) -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") # => ["name2"=>"hello", "k1"=>"mine"] +keyword_args() # => ["name2"=>"hello", "k1"=>4] -# 可以组合各种类型的参数在同一个函数的参数列表中 +# 可以在一个函数中组合各种类型的参数 function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo") println("normal arg: $normal_arg") println("optional arg: $optional_positional_arg") println("keyword arg: $keyword_arg") end +# => all_the_args (generic function with 2 methods) all_the_args(1, 3, keyword_arg=4) -# prints: -# normal arg: 1 -# optional arg: 3 -# keyword arg: 4 +# => normal arg: 1 +# => optional arg: 3 +# => keyword arg: 4 # Julia 有一等函数 function create_adder(x) @@ -443,14 +508,16 @@ function create_adder(x) end return adder end +# => create_adder (generic function with 1 method) # 这是用 "stabby lambda syntax" 创建的匿名函数 (x -> x > 2)(3) # => true -# 这个函数和上面的 create_adder 一模一样 +# 这个函数和上面的 create_adder 是等价的 function create_adder(x) y -> x + y end +# => create_adder (generic function with 1 method) # 你也可以给内部函数起个名字 function create_adder(x) @@ -459,18 +526,19 @@ function create_adder(x) end adder end +# => create_adder (generic function with 1 method) -add_10 = create_adder(10) -add_10(3) # => 13 - +add_10 = create_adder(10) # => (::getfield(Main, Symbol("#adder#11")){Int64}) + # (generic function with 1 method) +add_10(3) # => 13 # 内置的高阶函数有 -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] -# 还可以使用 list comprehensions 替代 map -[add_10(i) for i=[1, 2, 3]] # => [11, 12, 13] -[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] +# 还可以使用 list comprehensions 让 map 更美观 +[add_10(i) for i = [1, 2, 3]] # => [11, 12, 13] +[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] #################################################### ## 5. 类型 @@ -482,248 +550,315 @@ filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7] typeof(5) # => Int64 # 类型是一等值 -typeof(Int64) # => DataType -typeof(DataType) # => DataType +typeof(Int64) # => DataType +typeof(DataType) # => DataType # DataType 是代表类型的类型,也代表他自己的类型 -# 类型可用作文档化,优化,以及调度 -# 并不是静态检查类型 +# 类型可用于文档化代码、执行优化以及多重派分(dispatch) +# Julia 并不只是静态的检查类型 # 用户还可以自定义类型 -# 跟其他语言的 records 或 structs 一样 -# 用 `type` 关键字定义新的类型 +# 就跟其它语言的 record 或 struct 一样 +# 用 `struct` 关键字定义新的类型 -# type Name +# struct Name # field::OptionalType # ... # end -type Tiger - taillength::Float64 - coatcolor # 不附带类型标注的相当于 `::Any` +struct Tiger + taillength::Float64 + coatcolor # 不带类型标注相当于 `::Any` end -# 构造函数参数是类型的属性 -tigger = Tiger(3.5,"orange") # => Tiger(3.5,"orange") +# 默认构造函数的参数是类型的属性,按类型定义中的顺序排列 +tigger = Tiger(3.5, "orange") # => Tiger(3.5, "orange") # 用新类型作为构造函数还会创建一个类型 -sherekhan = typeof(tigger)(5.6,"fire") # => Tiger(5.6,"fire") +sherekhan = typeof(tigger)(5.6, "fire") # => Tiger(5.6, "fire") -# struct 类似的类型被称为具体类型 -# 他们可被实例化但不能有子类型 +# 类似 struct 的类型被称为具体类型 +# 它们可被实例化,但不能有子类型 # 另一种类型是抽象类型 -# abstract Name -abstract Cat # just a name and point in the type hierarchy +# 抽象类型名 +abstract type Cat end # 仅仅是指向类型结构层次的一个名称 -# 抽象类型不能被实例化,但是可以有子类型 +# 抽象类型不能被实例化,但可以有子类型 # 例如,Number 就是抽象类型 -subtypes(Number) # => 6-element Array{Any,1}: - # Complex{Float16} - # Complex{Float32} - # Complex{Float64} - # Complex{T<:Real} - # ImaginaryUnit - # Real -subtypes(Cat) # => 0-element Array{Any,1} - -# 所有的类型都有父类型; 可以用函数 `super` 得到父类型. +subtypes(Number) # => 2-element Array{Any,1}: + # => Complex + # => Real +subtypes(Cat) # => 0-element Array{Any,1} + +# AbstractString,类如其名,也是一个抽象类型 +subtypes(AbstractString) # => 4-element Array{Any,1}: + # => String + # => SubString + # => SubstitutionString + # => Test.GenericString + +# 所有的类型都有父类型。可以用函数 `supertype` 得到父类型 typeof(5) # => Int64 -super(Int64) # => Signed -super(Signed) # => Real -super(Real) # => Number -super(Number) # => Any -super(super(Signed)) # => Number -super(Any) # => Any -# 所有这些类型,除了 Int64, 都是抽象类型. - -# <: 是类型集成操作符 -type Lion <: Cat # Lion 是 Cat 的子类型 - mane_color - roar::String +supertype(Int64) # => Signed +supertype(Signed) # => Integer +supertype(Integer) # => Real +supertype(Real) # => Number +supertype(Number) # => Any +supertype(supertype(Signed)) # => Real +supertype(Any) # => Any +# 除了 Int64 外,其余的类型都是抽象类型 +typeof("fire") # => String +supertype(String) # => AbstractString +supertype(AbstractString) # => Any +supertype(SubString) # => AbstractString + +# <: 是子类型化操作符 +struct Lion <: Cat # Lion 是 Cat 的子类型 + mane_color + roar::AbstractString end # 可以继续为你的类型定义构造函数 -# 只需要定义一个同名的函数 -# 并调用已有的构造函数设置一个固定参数 -Lion(roar::String) = Lion("green",roar) -# 这是一个外部构造函数,因为他再类型定义之外 - -type Panther <: Cat # Panther 也是 Cat 的子类型 - eye_color - Panther() = new("green") - # Panthers 只有这个构造函数,没有默认构造函数 +# 只需要定义一个与类型同名的函数,并调用已有的构造函数得到正确的类型 +Lion(roar::AbstractString) = Lion("green", roar) # => Lion +# 这是一个外部构造函数,因为它在类型定义之外 + +struct Panther <: Cat # Panther 也是 Cat 的子类型 + eye_color + Panther() = new("green") + # Panthers 只有这个构造函数,没有默认构造函数 end -# 使用内置构造函数,如 Panther,可以让你控制 -# 如何构造类型的值 -# 应该尽可能使用外部构造函数而不是内部构造函数 +# 像 Panther 一样使用内置构造函数,让你可以控制如何构建类型的值 +# 应该尽量使用外部构造函数,而不是内部构造函数 #################################################### ## 6. 多分派 #################################################### -# 在Julia中, 所有的具名函数都是类属函数 -# 这意味着他们都是有很大小方法组成的 -# 每个 Lion 的构造函数都是类属函数 Lion 的方法 +# Julia 中所有的函数都是通用函数,或者叫做泛型函数(generic functions) +# 也就是说这些函数都是由许多小方法组合而成的 +# Lion 的每一种构造函数都是通用函数 Lion 的一个方法 # 我们来看一个非构造函数的例子 +# 首先,让我们定义一个函数 meow -# Lion, Panther, Tiger 的 meow 定义为 +# Lion, Panther, Tiger 的 meow 定义分别为 function meow(animal::Lion) - animal.roar # 使用点符号访问属性 + animal.roar # 使用点记号「.」访问属性 end +# => meow (generic function with 1 method) function meow(animal::Panther) - "grrr" + "grrr" end +# => meow (generic function with 2 methods) function meow(animal::Tiger) - "rawwwr" + "rawwwr" end +# => meow (generic function with 3 methods) # 试试 meow 函数 -meow(tigger) # => "rawwr" -meow(Lion("brown","ROAAR")) # => "ROAAR" +meow(tigger) # => "rawwwr" +meow(Lion("brown", "ROAAR")) # => "ROAAR" meow(Panther()) # => "grrr" -# 再看看层次结构 -issubtype(Tiger,Cat) # => false -issubtype(Lion,Cat) # => true -issubtype(Panther,Cat) # => true +# 回顾类型的层次结构 +Tiger <: Cat # => false +Lion <: Cat # => true +Panther <: Cat # => true -# 定义一个接收 Cats 的函数 +# 定义一个接收 Cat 类型的函数 function pet_cat(cat::Cat) - println("The cat says $(meow(cat))") + println("The cat says $(meow(cat))") end +# => pet_cat (generic function with 1 method) -pet_cat(Lion("42")) # => prints "The cat says 42" +pet_cat(Lion("42")) # => The cat says 42 try - pet_cat(tigger) # => ERROR: no method pet_cat(Tiger,) + pet_cat(tigger) # => ERROR: MethodError: no method matching pet_cat(::Tiger) catch e println(e) end # 在面向对象语言中,通常都是单分派 -# 这意味着分派方法是通过第一个参数的类型决定的 -# 在Julia中, 所有参数类型都会被考虑到 +# 这意味着使用的方法取决于第一个参数的类型 +# 而 Julia 中选择方法时会考虑到所有参数的类型 -# 让我们定义有多个参数的函数,好看看区别 -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()) # => The orange tiger wins! +fight(tigger, Lion("ROAR")) # => fight(tigger, Lion("ROAR")) -# 让我们修改一下传入具体为 Lion 类型时的行为 -fight(t::Tiger,l::Lion) = println("The $(l.mane_color)-maned lion wins!") +# 让我们修改一下传入 Lion 类型时的行为 +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()) # => The orange tiger wins! +fight(tigger, Lion("ROAR")) # => The green-maned lion wins! -# 把 Tiger 去掉 -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()) # => The victorious cat says grrr try - fight(Panther(),Lion("RAWR")) # => ERROR: no method fight(Panther,Lion) -catch + fight(Panther(), Lion("RAWR")) + # => ERROR: MethodError: no method matching fight(::Panther, ::Lion) + # => Closest candidates are: + # => fight(::Tiger, ::Lion) at ... + # => fight(::Tiger, ::Cat) at ... + # => fight(::Lion, ::Cat) at ... + # => ... +catch e + println(e) end -# 在试试让 Cat 在前面 -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 方法 -fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The victorious cat says rarrr -# 结果在老版本 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 - - -# Under the hood -# 你还可以看看 llvm 以及生成的汇编代码 - -square_area(l) = l * l # square_area (generic function with 1 method) - -square_area(5) #25 - -# 给 square_area 一个整形时发生什么 -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 - -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 - -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 - # -# 注意 只要参数中又浮点类型,Julia 就使用浮点指令 +# 试试把 Cat 放在前面 +fight(c::Cat, l::Lion) = println("The cat beats the Lion") +# => fight (generic function with 4 methods) + +# 由于无法判断该使用哪个 fight 方法,而产生了错误 +try + fight(Lion("RAR"), Lion("brown", "rarrr")) + # => ERROR: MethodError: fight(::Lion, ::Lion) is ambiguous. Candidates: + # => fight(c::Cat, l::Lion) in Main at ... + # => fight(l::Lion, c::Cat) in Main at ... + # => Possible fix, define + # => fight(::Lion, ::Lion) + # => ... +catch e + println(e) +end +# 在不同版本的 Julia 中错误信息可能有所不同 + +fight(l::Lion, l2::Lion) = println("The lions come to a tie") +# => fight (generic function with 5 methods) +fight(Lion("RAR"), Lion("brown", "rarrr")) # => The lions come to a tie + + +# 深入编译器之后 +# 你还可以看看 llvm 以及它生成的汇编代码 + +square_area(l) = l * l # => square_area (generic function with 1 method) +square_area(5) # => 25 + +# 当我们喂给 square_area 一个整数时会发生什么? +code_native(square_area, (Int32,), syntax = :intel) + # .text + # ; Function square_area { + # ; Location: REPL[116]:1 # 函数序言 (Prologue) + # push rbp + # mov rbp, rsp + # ; Function *; { + # ; Location: int.jl:54 + # imul ecx, ecx # 求 l 的平方,并把结果放在 ECX 中 + # ;} + # mov eax, ecx + # pop rbp # 还原旧的基址指针(base pointer) + # ret # 返回值放在 EAX 中 + # nop dword ptr [rax + rax] + # ;} +# 使用 syntax 参数指定输出语法。默认为 AT&T 格式,这里指定为 Intel 格式 + +code_native(square_area, (Float32,), syntax = :intel) + # .text + # ; Function square_area { + # ; Location: REPL[116]:1 + # push rbp + # mov rbp, rsp + # ; Function *; { + # ; Location: float.jl:398 + # vmulss xmm0, xmm0, xmm0 # 标量双精度乘法 (AVX) + # ;} + # pop rbp + # ret + # nop word ptr [rax + rax] + # ;} + +code_native(square_area, (Float64,), syntax = :intel) + # .text + # ; Function square_area { + # ; Location: REPL[116]:1 + # push rbp + # mov rbp, rsp + # ; Function *; { + # ; Location: float.jl:399 + # vmulsd xmm0, xmm0, xmm0 # 标量双精度乘法 (AVX) + # ;} + # pop rbp + # ret + # nop word ptr [rax + rax] + # ;} + +# 注意!只要参数中有浮点数,Julia 就会使用浮点指令 # 让我们计算一下圆的面积 -circle_area(r) = pi * r * r # circle_area (generic function with 1 method) -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 - # - -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 - # +circle_area(r) = pi * r * r # => circle_area (generic function with 1 method) +circle_area(5) # => 78.53981633974483 + +code_native(circle_area, (Int32,), syntax = :intel) + # .text + # ; Function circle_area { + # ; Location: REPL[121]:1 + # push rbp + # mov rbp, rsp + # ; Function *; { + # ; Location: operators.jl:502 + # ; Function *; { + # ; Location: promotion.jl:314 + # ; Function promote; { + # ; Location: promotion.jl:284 + # ; Function _promote; { + # ; Location: promotion.jl:261 + # ; Function convert; { + # ; Location: number.jl:7 + # ; Function Type; { + # ; Location: float.jl:60 + # vcvtsi2sd xmm0, xmm0, ecx # 从内存中读取整数 r + # movabs rax, 497710928 # 读取 pi + # ;}}}}} + # ; Function *; { + # ; Location: float.jl:399 + # vmulsd xmm1, xmm0, qword ptr [rax] # pi * r + # vmulsd xmm0, xmm1, xmm0 # (pi * r) * r + # ;}} + # pop rbp + # ret + # nop dword ptr [rax] + # ;} + +code_native(circle_area, (Float64,), syntax = :intel) + # .text + # ; Function circle_area { + # ; Location: REPL[121]:1 + # push rbp + # mov rbp, rsp + # movabs rax, 497711048 + # ; Function *; { + # ; Location: operators.jl:502 + # ; Function *; { + # ; Location: promotion.jl:314 + # ; Function *; { + # ; Location: float.jl:399 + # vmulsd xmm1, xmm0, qword ptr [rax] + # ;}}} + # ; Function *; { + # ; Location: float.jl:399 + # vmulsd xmm0, xmm1, xmm0 + # ;} + # pop rbp + # ret + # nop dword ptr [rax + rax] + # ;} ``` + +## 拓展阅读材料 + +你可以在 [Julia 中文文档](http://docs.juliacn.com/latest/) / [Julia 文档(en)](https://docs.julialang.org/) +中获得关于 Julia 的更多细节。 + +如果有任何问题可以去 [Julia 中文社区](http://discourse.juliacn.com/) / [官方社区(en)](https://discourse.julialang.org/) 提问,大家对待新手都非常的友好。 diff --git a/zh-cn/matlab-cn.html.markdown b/zh-cn/matlab-cn.html.markdown index 2fbccfc4..d215755c 100644 --- a/zh-cn/matlab-cn.html.markdown +++ b/zh-cn/matlab-cn.html.markdown @@ -10,9 +10,12 @@ lang: zh-cn ---
-MATLAB 是 MATrix LABoratory (矩阵实验室)的缩写,它是一种功能强大的数值计算语言,在工程和数学领域中应用广泛。
+MATLAB 是 MATrix LABoratory(矩阵实验室)的缩写。
+它是一种功能强大的数值计算语言,在工程和数学领域中应用广泛。
-如果您有任何需要反馈或交流的内容,请联系本教程作者[@the_ozzinator](https://twitter.com/the_ozzinator)、[osvaldo.t.mendoza@gmail.com](mailto:osvaldo.t.mendoza@gmail.com)。
+如果您有任何需要反馈或交流的内容,请联系本教程作者:
+[@the_ozzinator](https://twitter.com/the_ozzinator)
+或 [osvaldo.t.mendoza@gmail.com](mailto:osvaldo.t.mendoza@gmail.com)。
```matlab
% 以百分号作为注释符
@@ -45,7 +48,7 @@ edit('myfunction.m') % 在编辑器中打开指定函数或脚本 type('myfunction.m') % 在命令窗口中打印指定函数或脚本的源码
profile on % 打开 profile 代码分析工具
-profile of % 关闭 profile 代码分析工具
+profile off % 关闭 profile 代码分析工具
profile viewer % 查看 profile 代码分析工具的分析结果
help command % 在命令窗口中显示指定命令的帮助文档
@@ -113,7 +116,7 @@ b(2) % ans = 符 % 元组(cell 数组)
a = {'one', 'two', 'three'}
a(1) % ans = 'one' - 返回一个元组
-char(a(1)) % ans = one - 返回一个字符串
+a{1} % ans = one - 返回一个字符串
% 结构体
@@ -210,8 +213,8 @@ size(A) % 返回矩阵的行数和列数,ans = 3 3 A(1, :) =[] % 删除矩阵的第 1 行
A(:, 1) =[] % 删除矩阵的第 1 列
-transpose(A) % 矩阵转置,等价于 A'
-ctranspose(A) % 矩阵的共轭转置(对矩阵中的每个元素取共轭复数)
+transpose(A) % 矩阵(非共轭)转置,等价于 A.' (注意!有个点)
+ctranspose(A) % 矩阵的共轭转置(对矩阵中的每个元素取共轭复数),等价于 A'
% 元素运算 vs. 矩阵运算
@@ -219,18 +222,20 @@ ctranspose(A) % 矩阵的共轭转置(对矩阵中的每个元素取共轭复 % 在运算符加上英文句点就是对矩阵中的元素进行元素计算
% 示例如下:
A * B % 矩阵乘法,要求 A 的列数等于 B 的行数
-A .* B % 元素乘法,要求 A 和 B 形状一致(A 的行数等于 B 的行数, A 的列数等于 B 的列数)
-% 元素乘法的结果是与 A 和 B 形状一致的矩阵,其每个元素等于 A 对应位置的元素乘 B 对应位置的元素
+A .* B % 元素乘法,要求 A 和 B 形状一致,即两矩阵行列数完全一致
+ % 元素乘法的结果是与 A 和 B 形状一致的矩阵
+ % 其每个元素等于 A 对应位置的元素乘 B 对应位置的元素
% 以下函数中,函数名以 m 结尾的执行矩阵运算,其余执行元素运算:
exp(A) % 对矩阵中每个元素做指数运算
expm(A) % 对矩阵整体做指数运算
sqrt(A) % 对矩阵中每个元素做开方运算
-sqrtm(A) % 对矩阵整体做开放运算(即试图求出一个矩阵,该矩阵与自身的乘积等于 A 矩阵)
+sqrtm(A) % 对矩阵整体做开方运算(即试图求出一个矩阵,该矩阵与自身的乘积等于 A 矩阵)
% 绘图
-x = 0:.10:2*pi; % 生成一向量,其元素从 0 开始,以 0.1 的间隔一直递增到 2*pi(pi 就是圆周率)
+x = 0:0.1:2*pi; % 生成一向量,其元素从 0 开始,以 0.1 的间隔一直递增到 2*pi
+ % 其中 pi 为圆周率
y = sin(x);
plot(x,y)
xlabel('x axis')
@@ -288,7 +293,10 @@ clf clear % 清除图形窗口中的图像,并重置图像属性 % 也可以用 gcf 函数返回当前图像的句柄
h = plot(x, y); % 在创建图像时显式地保存图像句柄
set(h, 'Color', 'r')
-% 颜色代码:'y' 黄色,'m' 洋红色,'c' 青色,'r' 红色,'g' 绿色,'b' 蓝色,'w' 白色,'k' 黑色
+% 颜色代码:
+% 'y' 黄色,'m' 洋红,'c' 青色
+% 'r' 红色,'g' 绿色,'b' 蓝色
+% 'w' 白色,'k' 黑色
set(h, 'Color', [0.5, 0.5, 0.4])
% 也可以使用 RGB 值指定颜色
set(h, 'LineStyle', '--')
@@ -328,7 +336,8 @@ load('myFileName.mat') % 将指定文件中的变量载入到当前工作空间 % 与脚本文件类似,同样以 .m 作为后缀名
% 但函数文件可以接受用户输入的参数并返回运算结果
% 并且函数拥有自己的工作空间(变量域),不必担心变量名称冲突
-% 函数文件的名称应当与其所定义的函数的名称一致(比如下面例子中函数文件就应命名为 double_input.m)
+% 函数文件的名称应当与其所定义的函数的名称一致
+% 比如下面例子中函数文件就应命名为 double_input.m
% 使用 'help double_input.m' 可返回函数定义中第一行注释信息
function output = double_input(x)
% double_input(x) 返回 x 的 2 倍
@@ -463,14 +472,16 @@ triu(x) % 返回 x 的上三角这部分 tril(x) % 返回 x 的下三角这部分
cross(A, B) % 返回 A 和 B 的叉积(矢量积、外积)
dot(A, B) % 返回 A 和 B 的点积(数量积、内积),要求 A 和 B 必须等长
-transpose(A) % A 的转置,等价于 A'
+transpose(A) % 矩阵(非共轭)转置,等价于 A.' (注意!有个点)
fliplr(A) % 将一个矩阵左右翻转
flipud(A) % 将一个矩阵上下翻转
% 矩阵分解
-[L, U, P] = lu(A) % LU 分解:PA = LU,L 是下三角阵,U 是上三角阵,P 是置换阵
-[P, D] = eig(A) % 特征值分解:AP = PD,D 是由特征值构成的对角阵,P 的各列就是对应的特征向量
-[U, S, V] = svd(X) % 奇异值分解:XV = US,U 和 V 是酉矩阵,S 是由奇异值构成的半正定实数对角阵
+[L, U, P] = lu(A) % LU 分解:PA = LU,L 是下三角阵,U 是上三角阵,P 是置换阵
+[P, D] = eig(A) % 特征值分解:AP = PD
+ % D 是由特征值构成的对角阵,P 的各列就是对应的特征向量
+[U, S, V] = svd(X) % 奇异值分解:XV = US
+ % U 和 V 是酉矩阵,S 是由奇异值构成的半正定实数对角阵
% 常用向量函数
max % 最大值
@@ -489,5 +500,5 @@ perms(x) % x 元素的全排列 ## 相关资料
-* 官方网页:[http://http://www.mathworks.com/products/matlab/](http://www.mathworks.com/products/matlab/)
-* 官方论坛:[http://www.mathworks.com/matlabcentral/answers/](http://www.mathworks.com/matlabcentral/answers/)
+* 官方网页:[MATLAB - 技术计算语言 - MATLAB & Simulink](https://ww2.mathworks.cn/products/matlab.html)
+* 官方论坛:[MATLAB Answers - MATLAB Central](https://ww2.mathworks.cn/matlabcentral/answers/)
diff --git a/zh-cn/python3-cn.html.markdown b/zh-cn/python3-cn.html.markdown index 211ce0c5..fd962305 100644 --- a/zh-cn/python3-cn.html.markdown +++ b/zh-cn/python3-cn.html.markdown @@ -10,13 +10,13 @@ filename: learnpython3-cn.py lang: zh-cn --- -Python是由吉多·范罗苏姆(Guido Van Rossum)在90年代早期设计。它是如今最常用的编程 -语言之一。它的语法简洁且优美,几乎就是可执行的伪代码。 +Python 是由吉多·范罗苏姆(Guido Van Rossum)在 90 年代早期设计。 +它是如今最常用的编程语言之一。它的语法简洁且优美,几乎就是可执行的伪代码。 -欢迎大家斧正。英文版原作Louie Dinh [@louiedinh](http://twitter.com/louiedinh) -或着Email louiedinh [at] [谷歌的信箱服务]。中文翻译Geoff Liu。 +欢迎大家斧正。英文版原作 Louie Dinh [@louiedinh](http://twitter.com/louiedinh) +邮箱 louiedinh [at] [谷歌的信箱服务]。中文翻译 Geoff Liu。 -注意:这篇教程是特别为Python3写的。如果你想学旧版Python2,我们特别有另一篇教程。 +注意:这篇教程是基于 Python 3 写的。如果你想学旧版 Python 2,我们特别有[另一篇教程](http://learnxinyminutes.com/docs/python/)。 ```python @@ -70,15 +70,15 @@ not True # => False not False # => True # 逻辑运算符,注意and和or都是小写 -True and False #=> False -False or True #=> True +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 +0 and 2 # => 0 +-5 or 0 # => -5 +0 == False # => True +2 == True # => False +1 == True # => True # 用==判断相等 1 == 1 # => True @@ -113,10 +113,11 @@ False or True #=> True # 可以重复参数以节省时间 "{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick") -#=> "Jack be nimble, Jack be quick, Jack jump over the candle stick" +# => "Jack be nimble, Jack be quick, Jack jump over the candle stick" # 如果不想数参数,可以用关键字 -"{name} wants to eat {food}".format(name="Bob", food="lasagna") #=> "Bob wants to eat lasagna" +"{name} wants to eat {food}".format(name="Bob", food="lasagna") +# => "Bob wants to eat lasagna" # 如果你的Python3程序也要在Python2.5以下环境运行,也可以用老式的格式化语法 "%s can be %s the %s way" % ("strings", "interpolated", "old") @@ -132,8 +133,8 @@ None is None # => True # 所有其他值都是True bool(0) # => False bool("") # => False -bool([]) #=> False -bool({}) #=> False +bool([]) # => False +bool({}) # => False #################################################### @@ -233,7 +234,8 @@ filled_dict = {"one": 1, "two": 2, "three": 3} filled_dict["one"] # => 1 -# 用keys获得所有的键。因为keys返回一个可迭代对象,所以在这里把结果包在list里。我们下面会详细介绍可迭代。 +# 用 keys 获得所有的键。 +# 因为 keys 返回一个可迭代对象,所以在这里把结果包在 list 里。我们下面会详细介绍可迭代。 # 注意:字典键的顺序是不定的,你得到的结果可能和以下不同。 list(filled_dict.keys()) # => ["three", "two", "one"] @@ -261,7 +263,7 @@ filled_dict.setdefault("five", 5) # filled_dict["five"]设为5 filled_dict.setdefault("five", 6) # filled_dict["five"]还是5 # 字典赋值 -filled_dict.update({"four":4}) #=> {"one": 1, "two": 2, "three": 3, "four": 4} +filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4} filled_dict["four"] = 4 # 另一种赋值方法 # 用del删除 @@ -362,7 +364,7 @@ else: # else语句是可选的,必须在所有的except之后 filled_dict = {"one": 1, "two": 2, "three": 3} our_iterable = filled_dict.keys() -print(our_iterable) # => range(1,10) 是一个实现可迭代接口的对象 +print(our_iterable) # => dict_keys(['one', 'two', 'three']),是一个实现可迭代接口的对象 # 可迭代对象可以遍历 for i in our_iterable: @@ -376,17 +378,17 @@ our_iterator = iter(our_iterable) # 迭代器是一个可以记住遍历的位置的对象 # 用__next__可以取得下一个元素 -our_iterator.__next__() #=> "one" +our_iterator.__next__() # => "one" # 再一次调取__next__时会记得位置 -our_iterator.__next__() #=> "two" -our_iterator.__next__() #=> "three" +our_iterator.__next__() # => "two" +our_iterator.__next__() # => "three" # 当迭代器所有元素都取出后,会抛出StopIteration our_iterator.__next__() # 抛出StopIteration # 可以用list一次取出迭代器所有的元素 -list(filled_dict.keys()) #=> Returns ["one", "two", "three"] +list(filled_dict.keys()) # => Returns ["one", "two", "three"] diff --git a/zh-cn/swift-cn.html.markdown b/zh-cn/swift-cn.html.markdown index c25b2918..18bc52ed 100644 --- a/zh-cn/swift-cn.html.markdown +++ b/zh-cn/swift-cn.html.markdown @@ -110,7 +110,7 @@ anyObjectVar = "Changed value to a string, not good practice, but possible." // -// Mark: 数组与字典(关联数组) +// MARK: 数组与字典(关联数组) // /* @@ -214,9 +214,9 @@ func greet(name: String, day: String) -> String { } greet("Bob", day: "Tuesday") -// 第一个参数表示外部参数名和内部参数名使用同一个名称。 +// 第一个参数`_`表示不使用外部参数名,忽略`_`表示外部参数名和内部参数名使用同一个名称。 // 第二个参数表示外部参数名使用 `externalParamName` ,内部参数名使用 `localParamName` -func greet2(requiredName requiredName: String, externalParamName localParamName: String) -> String { +func greet2(_ requiredName: String, externalParamName localParamName: String) -> String { return "Hello \(requiredName), the day is \(localParamName)" } greet2(requiredName:"John", externalParamName: "Sunday") // 调用时,使用命名参数来指定参数的值 @@ -250,7 +250,7 @@ var increment = makeIncrementer() increment(7) // 强制进行指针传递 (引用传递),使用 `inout` 关键字修饰函数参数 -func swapTwoInts(inout a: Int, inout b: Int) { +func swapTwoInts(a: inout Int, b: inout Int) { let tempA = a a = b b = tempA @@ -521,7 +521,7 @@ class MyShape: Rect { // 在 optional 属性,方法或下标运算符后面加一个问号,可以优雅地忽略 nil 值,返回 nil。 // 这样就不会引起运行时错误 (runtime error) - if let reshape = self.delegate?.canReshape?() where reshape { + if let reshape = self.delegate?.canReshape?() { // 注意语句中的问号 self.delegate?.reshape?() } @@ -575,10 +575,10 @@ print(foundAtIndex == 2) // true // 自定义运算符可以以下面的字符打头: // / = - + * % < > ! & | ^ . ~ // 甚至是 Unicode 的数学运算符等 -prefix operator !!! {} +prefix operator !!! // 定义一个前缀运算符,使矩形的边长放大三倍 -prefix func !!! (inout shape: Square) -> Square { +prefix func !!! (shape: inout Square) -> Square { shape.sideLength *= 3 return shape } @@ -591,8 +591,8 @@ print(mySquare.sideLength) // 4 print(mySquare.sideLength) // 12 // 运算符也可以是泛型 -infix operator <-> {} -func <-><T: Equatable> (inout a: T, inout b: T) { +infix operator <-> +func <-><T: Equatable> (a: inout T, b: inout T) { let c = a a = b b = c |