From 667174e0caf6fbbb67aa70c9b39060706e568ae6 Mon Sep 17 00:00:00 2001 From: agbohub <14964685+agbohub@users.noreply.github.com> Date: Wed, 20 Apr 2022 18:12:47 +0800 Subject: =?UTF-8?q?Delete=20repeated=20word=20"one"=20in=20=C2=A7Intro?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vimscript.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vimscript.html.markdown b/vimscript.html.markdown index c2934af8..5bcaad45 100644 --- a/vimscript.html.markdown +++ b/vimscript.html.markdown @@ -11,7 +11,7 @@ contributors: " ############## " " Vim script (also called VimL) is the subset of Vim's ex-commands which -" supplies a number of features one one would expect from a scripting language, +" supplies a number of features one would expect from a scripting language, " such as values, variables, functions or loops. Always keep in the back of " your mind that a Vim script file is just a sequence of ex-commands. It is " very common for a script to mix programming-language features and raw -- cgit v1.2.3 From 524969c42c82e58fe1acf5ebcd9afe67a51142ca Mon Sep 17 00:00:00 2001 From: EmilySeville7cfg Date: Fri, 19 Aug 2022 09:47:37 +1000 Subject: Update bash help: - use snake case - fix examples - add notes to expansions --- bash.html.markdown | 86 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/bash.html.markdown b/bash.html.markdown index c9a805ba..4ab800a4 100644 --- a/bash.html.markdown +++ b/bash.html.markdown @@ -18,6 +18,7 @@ contributors: - ["Harry Mumford-Turner", "https://github.com/harrymt"] - ["Martin Nicholson", "https://github.com/mn113"] - ["Mark Grimwood", "https://github.com/MarkGrimwood"] + - ["Emily Grace Seville", "https://github.com/EmilySeville7cfg"] filename: LearnBash.sh translators: - ["Dimitri Kokkonis", "https://github.com/kokkonisd"] @@ -37,67 +38,68 @@ or executed directly in the shell. # As you already figured, comments start with #. Shebang is also a comment. # Simple hello world example: -echo Hello world! # => Hello world! +echo "Hello world!" # => Hello world! # Each command starts on a new line, or after a semicolon: -echo 'This is the first line'; echo 'This is the second line' -# => This is the first line -# => This is the second line +echo "This is the first command"; echo "This is the second command" +# => This is the first command +# => This is the second command # Declaring a variable looks like this: -Variable="Some string" +variable="Some string" # But not like this: -Variable = "Some string" # => returns error "Variable: command not found" -# Bash will decide that Variable is a command it must execute and give an error +variable = "Some string" # => returns error "variable: command not found" +# Bash will decide that `variable` is a command it must execute and give an error # because it can't be found. # Nor like this: -Variable= 'Some string' # => returns error: "Some string: command not found" -# Bash will decide that 'Some string' is a command it must execute and give an -# error because it can't be found. (In this case the 'Variable=' part is seen -# as a variable assignment valid only for the scope of the 'Some string' -# command.) +variable= "Some string" # => returns error: "Some string: command not found" +# Bash will decide that "Some string" is a command it must execute and give an +# error because it can't be found. In this case the "variable=" part is seen +# as a variable assignment valid only for the scope of the "Some string" +# command. # Using the variable: -echo $Variable # => Some string -echo "$Variable" # => Some string -echo '$Variable' # => $Variable +echo "$variable" # => Some string +echo '$variable' # => $variable # When you use the variable itself — assign it, export it, or else — you write # its name without $. If you want to use the variable's value, you should use $. # Note that ' (single quote) won't expand the variables! - -# Parameter expansion ${ }: -echo ${Variable} # => Some string -# This is a simple usage of parameter expansion -# Parameter Expansion gets a value from a variable. -# It "expands" or prints the value -# During the expansion time the value or parameter can be modified -# Below are other modifications that add onto this expansion - -# String substitution in variables -echo ${Variable/Some/A} # => A string -# This will substitute the first occurrence of "Some" with "A" - -# Substring from a variable -Length=7 -echo ${Variable:0:Length} # => Some st +# You can write variable without surrounding quotes but it's not recommended. + +# Parameter expansion ${...}: +echo "${variable}" # => Some string +# This is a simple usage of parameter expansion such as two examples above. +# Parameter expansion gets a value from a variable. +# It "expands" or prints the value. +# During the expansion time the value or parameter can be modified. +# Below are other modifications that add onto this expansion. + +# String substitution in variables: +echo "${variable/Some/A}" # => A string +# This will substitute the first occurrence of "Some" with "A". + +# Substring from a variable: +length=7 +echo "${variable:0:length}" # => Some st # This will return only the first 7 characters of the value -echo ${Variable: -5} # => tring -# This will return the last 5 characters (note the space before -5) +echo "${variable: -5}" # => tring +# This will return the last 5 characters (note the space before -5). +# The space before minus is mandatory here. -# String length -echo ${#Variable} # => 11 +# String length: +echo "${#variable}" # => 11 -# Indirect expansion -OtherVariable="Variable" -echo ${!OtherVariable} # => Some String -# This will expand the value of OtherVariable +# Indirect expansion: +other_variable="variable" +echo ${!other_variable} # => Some string +# This will expand the value of `other_variable`. -# Default value for variable -echo ${Foo:-"DefaultValueIfFooIsMissingOrEmpty"} +# Default value for variable: +echo "${foo:-"DefaultValueIfFooIsMissingOrEmpty"}" # => DefaultValueIfFooIsMissingOrEmpty -# This works for null (Foo=) and empty string (Foo=""); zero (Foo=0) returns 0. +# This works for null (foo=) and empty string (foo=""); zero (foo=0) returns 0. # Note that it only returns default value and doesn't change variable value. # Declare an array with 6 elements -- cgit v1.2.3 From ed1ca1c70e24dea4b92e7dcb3ac391de6988ca22 Mon Sep 17 00:00:00 2001 From: EmilySeville7cfg Date: Fri, 19 Aug 2022 09:53:55 +1000 Subject: Update bash help: - remove trailing spaces --- bash.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bash.html.markdown b/bash.html.markdown index 4ab800a4..3f1e8b70 100644 --- a/bash.html.markdown +++ b/bash.html.markdown @@ -42,8 +42,8 @@ echo "Hello world!" # => Hello world! # Each command starts on a new line, or after a semicolon: echo "This is the first command"; echo "This is the second command" -# => This is the first command -# => This is the second command +# => This is the first command +# => This is the second command # Declaring a variable looks like this: variable="Some string" -- cgit v1.2.3 From 242d5da837ff2458560431388b4848bae7e52e15 Mon Sep 17 00:00:00 2001 From: EmilySeville7cfg Date: Fri, 19 Aug 2022 10:10:34 +1000 Subject: Update bash help: - update examples of array manipulation - move built-in variables section one level up - add note in brace expansion --- bash.html.markdown | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/bash.html.markdown b/bash.html.markdown index 3f1e8b70..53c3d96c 100644 --- a/bash.html.markdown +++ b/bash.html.markdown @@ -102,39 +102,41 @@ echo "${foo:-"DefaultValueIfFooIsMissingOrEmpty"}" # This works for null (foo=) and empty string (foo=""); zero (foo=0) returns 0. # Note that it only returns default value and doesn't change variable value. -# Declare an array with 6 elements -array0=(one two three four five six) -# Print first element -echo $array0 # => "one" -# Print first element -echo ${array0[0]} # => "one" -# Print all elements -echo ${array0[@]} # => "one two three four five six" -# Print number of elements -echo ${#array0[@]} # => "6" -# Print number of characters in third element -echo ${#array0[2]} # => "5" -# Print 2 elements starting from fourth -echo ${array0[@]:3:2} # => "four five" -# Print all elements. Each of them on new line. -for i in "${array0[@]}"; do - echo "$i" +# Declare an array with 6 elements: +array=(one two three four five six) +# Print the first element: +echo "${array[0]}" # => "one" +# Print all elements: +echo "${array[@]}" # => "one two three four five six" +# Print the number of elements: +echo "${#array[@]}" # => "6" +# Print the number of characters in third element +echo "${#array[2]}" # => "5" +# Print 2 elements starting from fourth: +echo "${array[@]:3:2}" # => "four five" +# Print all elements each of them on new line. +for item in "${array[@]}"; do + echo "$item" done -# Brace Expansion { } -# Used to generate arbitrary strings -echo {1..10} # => 1 2 3 4 5 6 7 8 9 10 -echo {a..z} # => a b c d e f g h i j k l m n o p q r s t u v w x y z -# This will output the range from the start value to the end value - # Built-in variables: -# There are some useful built-in variables, like +# There are some useful built-in variables, like: echo "Last program's return value: $?" echo "Script's PID: $$" echo "Number of arguments passed to script: $#" echo "All arguments passed to script: $@" echo "Script's arguments separated into different variables: $1 $2..." +# Brace Expansion {...} +# used to generate arbitrary strings: +echo {1..10} # => 1 2 3 4 5 6 7 8 9 10 +echo {a..z} # => a b c d e f g h i j k l m n o p q r s t u v w x y z +# This will output the range from the start value to the end value. +# Note that you can't use variables here: +from=1 +to=10 +echo {$from..$to} # => {$from..$to} + # Now that we know how to echo and use variables, # let's learn some of the other basics of bash! -- cgit v1.2.3 From 7bcf933601fcdde118a2e745cb026b8c45910f51 Mon Sep 17 00:00:00 2001 From: EmilySeville7cfg Date: Fri, 19 Aug 2022 10:20:15 +1000 Subject: Update bash help: - small grammar enhancements --- bash.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bash.html.markdown b/bash.html.markdown index 53c3d96c..bccc5773 100644 --- a/bash.html.markdown +++ b/bash.html.markdown @@ -63,7 +63,7 @@ variable= "Some string" # => returns error: "Some string: command not found" # Using the variable: echo "$variable" # => Some string echo '$variable' # => $variable -# When you use the variable itself — assign it, export it, or else — you write +# When you use a variable itself — assign it, export it, or else — you write # its name without $. If you want to use the variable's value, you should use $. # Note that ' (single quote) won't expand the variables! # You can write variable without surrounding quotes but it's not recommended. @@ -96,7 +96,7 @@ other_variable="variable" echo ${!other_variable} # => Some string # This will expand the value of `other_variable`. -# Default value for variable: +# The default value for variable: echo "${foo:-"DefaultValueIfFooIsMissingOrEmpty"}" # => DefaultValueIfFooIsMissingOrEmpty # This works for null (foo=) and empty string (foo=""); zero (foo=0) returns 0. -- cgit v1.2.3 From 42040d6d7dbe4dc57c6ad21c02498b00fff4b596 Mon Sep 17 00:00:00 2001 From: EmilySeville7cfg Date: Fri, 19 Aug 2022 11:09:16 +1000 Subject: Update bash help: - refresh read command sample - fix if examples and && with || --- bash.html.markdown | 70 ++++++++++++++++++++++++------------------------------ 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/bash.html.markdown b/bash.html.markdown index bccc5773..e0e4f88a 100644 --- a/bash.html.markdown +++ b/bash.html.markdown @@ -138,7 +138,7 @@ to=10 echo {$from..$to} # => {$from..$to} # Now that we know how to echo and use variables, -# let's learn some of the other basics of bash! +# let's learn some of the other basics of Bash! # Our current directory is available through the command `pwd`. # `pwd` stands for "print working directory". @@ -148,33 +148,46 @@ echo "I'm in $(pwd)" # execs `pwd` and interpolates output echo "I'm in $PWD" # interpolates the variable # If you get too much output in your terminal, or from a script, the command -# `clear` clears your screen +# `clear` clears your screen: clear -# Ctrl-L also works for clearing output +# Ctrl-L also works for clearing output. # Reading a value from input: echo "What's your name?" -read Name # Note that we didn't need to declare a new variable -echo Hello, $Name! +read name +# Note that we didn't need to declare a new variable. +echo "Hello, $name!" -# We have the usual if structure: -# use `man test` for more info about conditionals -if [ $Name != $USER ] -then +# We have the usual if structure. +# Condition is true if the value of $name is not equal to the current user's login username: +if [[ "$name" != "$USER" ]]; then echo "Your name isn't your username" else echo "Your name is your username" fi -# True if the value of $Name is not equal to the current user's login username -# NOTE: if $Name is empty, bash sees the above condition as: -if [ != $USER ] -# which is invalid syntax -# so the "safe" way to use potentially empty variables in bash is: -if [ "$Name" != $USER ] ... -# which, when $Name is empty, is seen by bash as: -if [ "" != $USER ] ... -# which works as expected +# To use && and || with if statements, you need multiple pairs of square brackets: +read age +if [[ "$name" == "Steve" ]] && [[ "$age" -eq 15 ]]; then + echo "This will run if $name is Steve AND $age is 15." +fi + +if [[ "$name" == "Daniya" ]] || [[ "$name" == "Zach" ]]; then + echo "This will run if $name is Daniya OR Zach." +fi +# There are other comparison operators for numbers listed below: +# -ne - not equal +# -lt - less than +# -gt - greater than +# -le - less than or equal to +# -ge - greater than or equal to + +# There is also the `=~` operator, which tests a string against the Regex pattern: +email=me@example.com +if [[ "$email" =~ [a-z]+@[a-z]{2,}\.(com|net|org) ]] +then + echo "Valid email!" +fi # There is also conditional execution echo "Always executed" || echo "Only executed if first command fails" @@ -197,27 +210,6 @@ bg kill %2 # %1, %2, etc. can be used for fg and bg as well -# To use && and || with if statements, you need multiple pairs of square brackets: -if [ "$Name" == "Steve" ] && [ "$Age" -eq 15 ] -then - echo "This will run if $Name is Steve AND $Age is 15." -fi - -if [ "$Name" == "Daniya" ] || [ "$Name" == "Zach" ] -then - echo "This will run if $Name is Daniya OR Zach." -fi - -# There is also the `=~` operator, which tests a string against a Regex pattern: -Email=me@example.com -if [[ "$Email" =~ [a-z]+@[a-z]{2,}\.(com|net|org) ]] -then - echo "Valid email!" -fi -# Note that =~ only works within double [[ ]] square brackets, -# which are subtly different from single [ ]. -# See https://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs for more on this. - # Redefine command `ping` as alias to send only 5 packets alias ping='ping -c 5' # Escape the alias and use command with this name instead -- cgit v1.2.3 From cb4ab9ce037f5170da99006cf0ffb661a480a683 Mon Sep 17 00:00:00 2001 From: Bob DuCharme Date: Sat, 10 Sep 2022 09:35:12 -0400 Subject: Make color coding generic because too much was red --- rdf.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rdf.html.markdown b/rdf.html.markdown index 4cb7ddd0..5b2105b8 100644 --- a/rdf.html.markdown +++ b/rdf.html.markdown @@ -28,7 +28,7 @@ usually look like URLs but function as identifiers, not locators. The use of URIs provides context for resource identifiers to make them unambiguous—for example, to tell a book title from a job title. -```turtle +``` # The hash symbol is the comment delimiter. # Turtle triple statements end with periods like natural language sentences. -- cgit v1.2.3 From 44e15f80047d0675c421c38aadb2a8dc09d32d06 Mon Sep 17 00:00:00 2001 From: Yash Date: Mon, 10 Oct 2022 22:27:35 +0530 Subject: Added missing information about scanf --- c.html.markdown | 63 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/c.html.markdown b/c.html.markdown index a898f052..cd6b5ad2 100644 --- a/c.html.markdown +++ b/c.html.markdown @@ -2,15 +2,15 @@ language: C filename: learnc.c contributors: - - ["Adam Bard", "http://adambard.com/"] - - ["Árpád Goretity", "http://twitter.com/H2CO3_iOS"] - - ["Jakub Trzebiatowski", "http://cbs.stgn.pl"] - - ["Marco Scannadinari", "https://marcoms.github.io"] - - ["Zachary Ferguson", "https://github.io/zfergus2"] - - ["himanshu", "https://github.com/himanshu81494"] - - ["Joshua Li", "https://github.com/JoshuaRLi"] - - ["Dragos B. Chirila", "https://github.com/dchirila"] - - ["Heitor P. de Bittencourt", "https://github.com/heitorPB/"] + - ["Adam Bard", "http://adambard.com/"] + - ["Árpád Goretity", "http://twitter.com/H2CO3_iOS"] + - ["Jakub Trzebiatowski", "http://cbs.stgn.pl"] + - ["Marco Scannadinari", "https://marcoms.github.io"] + - ["Zachary Ferguson", "https://github.io/zfergus2"] + - ["himanshu", "https://github.com/himanshu81494"] + - ["Joshua Li", "https://github.com/JoshuaRLi"] + - ["Dragos B. Chirila", "https://github.com/dchirila"] + - ["Heitor P. de Bittencourt", "https://github.com/heitorPB/"] --- Ah, C. Still **the** language of modern high-performance computing. @@ -101,6 +101,12 @@ int main (int argc, char** argv) // %d is an integer, \n is a newline printf("%d\n", 0); // => Prints 0 + // take input using scanf + // '&' is used to define the location + // where we want to store the input value + int input; + scanf("%d", &input); + /////////////////////////////////////// // Types /////////////////////////////////////// @@ -118,7 +124,7 @@ int main (int argc, char** argv) // shorts are usually 2 bytes (use the `sizeof` operator to check) short x_short = 0; - // chars are defined as the smallest addressable unit for a processor. + // chars are defined as the smallest addressable unit for a processor. // This is usually 1 byte, but for some systems it can be more (ex. for TMS320 from TI it's 2 bytes). char x_char = 0; char y_char = 'y'; // Char literals are quoted with '' @@ -167,19 +173,19 @@ int main (int argc, char** argv) // where the "{0}" part is called an "array initializer". // All elements (if any) past the ones in the initializer are initialized to 0: int my_array[5] = {1, 2}; - // So my_array now has five elements, all but the first two of which are 0: + // So my_array now has five elements, all but the first two of which are 0: // [1, 2, 0, 0, 0] - // NOTE that you get away without explicitly declaring the size + // NOTE that you get away without explicitly declaring the size // of the array IF you initialize the array on the same line: int my_array[] = {0}; - // NOTE that, when not declaring the size, the size of the array is the number + // NOTE that, when not declaring the size, the size of the array is the number // of elements in the initializer. With "{0}", my_array is now of size one: [0] // To evaluate the size of the array at run-time, divide its byte size by the // byte size of its element type: size_t my_array_size = sizeof(my_array) / sizeof(my_array[0]); - // WARNING You should evaluate the size *before* you begin passing the array - // to functions (see later discussion) because arrays get "downgraded" to - // raw pointers when they are passed to functions (so the statement above + // WARNING You should evaluate the size *before* you begin passing the array + // to functions (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, @@ -247,11 +253,11 @@ int main (int argc, char** argv) (float)i1 / i2; // => 0.5f i1 / (double)i2; // => 0.5 // Same with double f1 / f2; // => 0.5, plus or minus epsilon - + // Floating-point numbers are defined by IEEE 754, thus cannot store perfectly - // exact values. For instance, the following does not produce expected results - // because 0.1 might actually be 0.099999999999 insided the computer, and 0.3 - // might be stored as 0.300000000001. + // exact values. For instance, the following does not produce expected results + // because 0.1 might actually be 0.099999999999 insided the computer, and 0.3 + // might be stored as 0.300000000001. (0.1 + 0.1 + 0.1) != 0.3; // => 1 (true) // and it is NOT associative due to reasons mentioned above. 1 + (1e123 - 1e123) != (1 + 1e123) - 1e123; // => 1 (true) @@ -262,7 +268,7 @@ int main (int argc, char** argv) // eventually calls C which uses IEEE 754. It is mentioned this way not to // indicate that this is a poor implementation, but instead as a warning // that when doing floating point comparisons, a little bit of error (epsilon) - // needs to be considered. + // needs to be considered. // Modulo is there as well, but be careful if arguments are negative 11 % 3; // => 2 as 11 = 2 + 3*x (x=3) @@ -411,7 +417,7 @@ int main (int argc, char** argv) */ /* it is generally considered bad practice to do so, except if - you really know what you are doing. See + you really know what you are doing. See https://en.wikipedia.org/wiki/Spaghetti_code#Meaning */ @@ -424,7 +430,7 @@ int main (int argc, char** argv) int x_hex = 0x01; // You can assign vars with hex literals // binary is not in the standard, but allowed by some - // compilers (x_bin = 0b0010010110) + // compilers (x_bin = 0b0010010110) // Casting between types will attempt to preserve their numeric values printf("%d\n", x_hex); // => Prints 1 @@ -626,7 +632,7 @@ printf("first: %d\nsecond: %d\n", first, second); // values will be swapped */ -// Return multiple values. +// Return multiple values. // C does not allow for returning multiple values with the return statement. If // you would like to return multiple values, then the caller must pass in the // variables where they would like the returned values to go. These variables must @@ -637,9 +643,9 @@ int return_multiple( int *array_of_3, int *ret1, int *ret2, int *ret3) return 0; //return error code (false) //de-reference the pointer so we modify its value - *ret1 = array_of_3[0]; - *ret2 = array_of_3[1]; - *ret3 = array_of_3[2]; + *ret1 = array_of_3[0]; + *ret2 = array_of_3[1]; + *ret3 = array_of_3[2]; return 1; //return error code (true) } @@ -901,10 +907,11 @@ Node createLinkedList(int *vals, int len); #endif /* End of the if precompiler directive. */ ``` + ## Further Reading Best to find yourself a copy of [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language) -It is *the* book about C, written by Dennis Ritchie, the creator of C, and Brian Kernighan. Be careful, though - it's ancient and it contains some +It is _the_ book about C, written by Dennis Ritchie, the creator of C, and Brian Kernighan. Be careful, though - it's ancient and it contains some inaccuracies (well, ideas that are not considered good anymore) or now-changed practices. Another good resource is [Learn C The Hard Way](http://learncodethehardway.org/c/) (not free). -- cgit v1.2.3 From c86c82f4b5081f542ea580088b53574c09b6688c Mon Sep 17 00:00:00 2001 From: "Stanislav (Stanley) Modrak" <44023416+smith558@users.noreply.github.com> Date: Wed, 26 Oct 2022 18:36:17 +0100 Subject: Update python.html.markdown --- python.html.markdown | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/python.html.markdown b/python.html.markdown index 4aeb93f4..2f91d452 100644 --- a/python.html.markdown +++ b/python.html.markdown @@ -419,7 +419,7 @@ for animal in ["dog", "cat", "mouse"]: """ "range(number)" returns an iterable of numbers -from zero to the given number +from zero up to (but excluding) the given number prints: 0 1 @@ -628,6 +628,12 @@ def set_global_x(num): set_x(43) set_global_x(6) +""" +prints: + 43 + 5 + 6 +""" # Python has first class functions -- cgit v1.2.3 From 610676c76efa7532975cfcc8dc5b8b69cdce1a84 Mon Sep 17 00:00:00 2001 From: "Stanislav (Stanley) Modrak" <44023416+smith558@users.noreply.github.com> Date: Wed, 26 Oct 2022 18:37:42 +0100 Subject: Update python.html.markdown --- python.html.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/python.html.markdown b/python.html.markdown index 2f91d452..22827963 100644 --- a/python.html.markdown +++ b/python.html.markdown @@ -9,6 +9,7 @@ contributors: - ["Rommel Martinez", "https://ebzzry.io"] - ["Roberto Fernandez Diaz", "https://github.com/robertofd1995"] - ["caminsha", "https://github.com/caminsha"] + - ["Stanislav Modrak", "https://stanislav.gq"] filename: learnpython.py --- -- cgit v1.2.3 From 25e194aa0fe8cb82ca8f68c14993d31bf55bf034 Mon Sep 17 00:00:00 2001 From: "Stanislav (Stanley) Modrak" <44023416+smith558@users.noreply.github.com> Date: Wed, 26 Oct 2022 19:30:44 +0100 Subject: Update python.html.markdown --- python.html.markdown | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/python.html.markdown b/python.html.markdown index 22827963..687529b5 100644 --- a/python.html.markdown +++ b/python.html.markdown @@ -613,15 +613,17 @@ y = 2 x, y = swap(x, y) # => x = 2, y = 1 # (x, y) = swap(x,y) # Again parenthesis have been excluded but can be included. -# Function Scope +# global scope x = 5 def set_x(num): - # Local var x not the same as global variable x + # local scope begins here + # local var x not the same as global var x x = num # => 43 print(x) # => 43 def set_global_x(num): + # global indicates that particular var lives in the global scope global x print(x) # => 5 x = num # global var x is now set to 6 -- cgit v1.2.3 From 940326953b4b9205e07ac83530eca7fb7c34946b Mon Sep 17 00:00:00 2001 From: Kemel Zaidan Date: Thu, 27 Oct 2022 15:46:18 -0300 Subject: add pt_br translation for Processing --- pt-br/processing-pt.html.markdown | 469 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 469 insertions(+) create mode 100644 pt-br/processing-pt.html.markdown diff --git a/pt-br/processing-pt.html.markdown b/pt-br/processing-pt.html.markdown new file mode 100644 index 00000000..dab5a98d --- /dev/null +++ b/pt-br/processing-pt.html.markdown @@ -0,0 +1,469 @@ +--- +language: processing +filename: learnprocessing.pde +contributors: + - ["Phone Thant Ko", "http://github.com/phonethantko"] + - ["Divay Prakash", "https://github.com/divayprakash"] +translators: + - ["Kemel Zaidan", "https://github.com/kemelzaidan"] +lang: pt-br +--- + +## Introdução + +Processing é uma linguagem de programação para criação de artes digitais e +conteúdo multimídia, permitindo que não programadores aprendam os fundamentos da +programação computacional em um contexto visual. + +Embora a linguagem seja baseada na linguagem Java, sua sintaxe foi amplamente +influenciado por ambas as sintaxes Java e Javascript. [Veja mais aqui](https://processing.org/reference/) + +A linguagem é tipada estaticamente e também vem com a sua IDE oficial para +compilar e executar os scripts. + +``` +/* --------- + Comentários + --------- +*/ + +// Comentário de linha única começa com // + +/* + Como o Processing é baseado em Java, + a sintaxe para seus comentários é a mesma do Java (como você deve ter notado acima)! + Comentários de várias linhas são agrupados como visto aqui. +*/ + +/* --------------------------------------- + Escrevendo e executando programas em Processing + --------------------------------------- +*/ + +// No Processing, o ponto de entrada do programa é uma função chamada setup() com um +// tipo de retorno void. +// Observação! A sintaxe é muito semelhante à do C++. +void setup() { + // Isso imprime a saída clássica "Hello World!" para o console quando executado. + println("Olá Mundo!"); // Outra linguagem com cilada para ponto-e-vígula, não é? +} + +// Normalmente, colocamos todos os códigos estáticos dentro do método setup() como o próprio nome +// sugere, uma vez que é executado apenas uma vez. +// Pode variar da definição das cores de fundo, ou o tamanho da tela. +background(color); //define a cor do fundo +size(largura,altura,[renderizador]); // define o tamanho da tela com parâmetro +// opcional para definir o renderizador +// Você verá mais sobre isso ao longo deste documento. + +// Se você deseja executar os códigos indefinidamente, eles devem ser colocados dentro do método draw() +// draw() deve existir caso você queira que o código seja executado continuamente e, obviamente, +// só pode haver um método draw(). +int = 0; +void draw(){ + // Este bloco de código faz um loop para sempre até parar + imprima(i); + i++; // Operador de incremento! +} + +// Agora que sabemos como escrever o script de trabalho e como executá-lo, +// continuaremos a explorar quais tipos de dados e coleções são suportados no +// Processing. + +/* ------------------------ + Tipos de dados e coleções + ------------------------ +*/ + +// De acordo com as Referências do Processing, ele suporta 8 tipos primitivos +// de dados da seguinte forma. + +boolean valorBoleano = true; // Boleano +byte valorByteDeA = 23; // Byte +char valorCharDeA = 'A'; // Caractere +color valorDeCorBrancoM = color(255, 255, 255); // Cor (especificada usando +// método color()) +color valorDeCorBrancoH = #FFFFFF; // Cor (especificada usando valor de hash) +int valor = 5; // Inteiro (Número sem decimais) +long valorLongo = 2147483648L; // "L" é adicionado ao número para marcá-lo como um longo +float valorFloat = 1,12345; // Float (números de ponto flutuante de 32 bits) +double valorDouble = 1,12345D; // Double (números de ponto flutuante de 64 bits) + +// NOTA! +// Embora os tipos de dados "long" e "double" funcionem na linguagem, +// funções do Processing não usam esses tipos de dados, portanto +// eles precisam ser convertidos em tipos de dados "int" e "float", respectivamente, +// usando a sintaxe (int) e (float) antes de passar para uma função. + +// Existem vários tipos de dados compostos que estão disponíveis por padrão para uso +// no Processing. +// Primeiramente, farei um resumo dos mais usados ​​para economizar tempo. + +// String +// Enquanto o tipo de dados char usa '', o tipo de dados String usa "" - aspas duplas. +string stringExemplo = "Olá, Processing!"; +// String também pode ser construída a partir de um array de tipos de dados char. Nós vamos +// discutir array muito em breve. +char fonte = {'H', 'E', 'L', 'L', 'O'}; +string stringDeFonte = new String(source); // HELLO +// Como em Java, strings podem ser concatenadas usando o operador "+". +print("Olá " + "Mundo!"); // Olá Mundo! + +// Array +// Arrays em Processing podem conter quaisquer tipos de dados, incluindo os próprios objetos. +// Como os arrays são semelhantes aos objetos, eles devem ser criados com a palavra-chave +// "new". +int[] arrayInt = new int[5]; +int[] arrayIntComValores ​​= {1, 2, 3}; // Você também pode preencher com dados. + +// Lista de Arrays +// As funções são semelhantes às do array; arraylists podem conter qualquer tipo de dados. +// A única diferença é que as listas de matrizes são redimensionadas dinamicamente, pois é uma forma de +// implementação de matriz redimensionável da interface "List" do Java . +ArrayList intArrayList = new ArrayList(); + +// Objeto +// Como é baseado em Java, o Processing suporta programação orientada a objetos. +// Isso significa que você pode basicamente definir quaisquer tipos de dados de sua preferência e manipulá-los +// para suas necessidades. +// Claro, uma classe tem que ser definida antes para o objeto que você quer. +// Formato --> NomeClasse NameInstancia +UmaClasseQualquer meuObjeto // então instancia mais tarde +//ou +UmaClasseQualquer meuObjetoInstanciado = new UmaClasseQualquer(); + +// O Processing surge com mais coleções (ex. - Dicionários e Listas) por +// padrão, por uma questão de simplicidade, vou deixá-los fora de discussão aqui. + +/* ------------ + Matemática + ------------ +*/ + +// Aritmética +1 + 1 // 2 +2 - 1 // 1 +2 * 3 // 6 +3/2 // 1 +3,0 / 2 // 1,5 +3,0% 2 // 1,0 + +// O Processing também vem com um conjunto de funções que simplificam operações matemáticas. +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 + +// Vetores +// O Processing fornece uma maneira fácil de implementar vetores em seu ambiente +// usando a classe PVector. Ela pode descrever um vetor bi ou tridimensional e +// vem com um conjunto de métodos que são úteis para operações com matrizes. +// Você pode encontrar mais informações sobre a classe PVector e suas funções aqui. +// (https://processing.org/reference/PVector.html) + +// Trigonometria +// O processamento também suporta operações trigonométricas fornecendo um conjunto de +// funções. sin(), cos(), tan(), asin(), acos(), atan() e também degrees() +// e radians() para conversão conveniente. +// No entanto, essas funções usam o ângulo em radianos como parâmetro, então é necessário +// converter previamente. +float um = sin(PI/2); // um = 1.0 +// Como você deve ter notado, existe um conjunto de constantes para usos trigonométricos; +// PI, HALF_PI, QUARTER_PI e assim por diante... + +/* ------------- + Controle de fluxo + ------------- +*/ + +// Declarações Condicionais +// Instruções If - A mesma sintaxe das instruções if em Java. +if (autor.getAppearance().equals("quente")) { + print("Narcisismo no seu melhor!"); +} senão { + // Você pode verificar outras condições aqui. + print("Algo está realmente errado aqui!"); +} +// Um ​​atalho para instruções if-else também pode ser usado. +int = 3; +Valor da string = (i > 5) ? "Grande" : "Pequena"; // "Pequena" + +// A estrutura switch-case pode ser usada para verificar várias condições de forma concisa. +// É importante usar a instrução break. Se a instrução `break` +// não existe o programa executa todos os casos a seguir após um caso ser verdadeiro. +int valor = 2; +switch(valor) { + case 0: + print("Nada!"); // Isso não é executado. + break; // Salta para a próxima instrução + case 1: + print("Chegando lá..."); // Isso novamente não é executado. + break; + case 2: + print("Bravo!"); // Esta linha é executada. + break; + default: + print("Não encontrado!"); // Esta linha é executada se nosso valor for algum outro valor. + break; +} + +// Declarações iterativas +// Declarações For - Novamente, a mesma sintaxe que em Java +for(int i = 0; i < 5; i++){ + print(i); // imprime de 0 a 4 +} + +// Declarações While - Novamente, nada de novo se você estiver familiarizado com a sintaxe Java. +int j = 3; +while(j > 0) { + print(j); + j--; // Isso é importante para evitar que o código seja executado indefinidamente. +} + +// loop()| noLoop() | redraw() | exit() +// Estas são mais funções específicas do Processing para configurar o fluxo do programa. +loop(); // permite que o método draw() seja executado para sempre enquanto +noLoop(); // só permite que ele seja executado uma vez. +redraw(); // executa o método draw() mais uma vez. +exit(); // Isso para o programa. É útil para programas com draw() +// rodando continuamente. +``` + +## Desenho com Processing + +Como você já deve ter entendido o básico da linguagem, vamos agora +veja a melhor parte do Processing - DESENHAR. + +``` +/* ------ + Formas + ------ +*/ + +// Formas 2D + +// Ponto +point(x, y); // No espaço 2D +point(x, y, z); // No espaço 3D +// Desenha um ponto no espaço de coordenadas. + +// Linha +line(x1, y1, x2, y2); // No espaço 2D +line(x1, y1, z1, x2, y2, z2); // No espaço 3D +// Desenha uma linha conectando dois pontos definidos por (x1, y1) e (x2, y2). + +// Triângulo +triangle(x1, y1, x2, y2, x3, y3); +// Desenha um triângulo conectando três pontos definidos por parâmetros de coordenadas. + +// Retângulo +rect(a, b, c, d, [r]); // Com parâmetro opcional definindo o raio de todos os cantos +rect(a, b, c, d, [tl, tr, br, bl]); // Com conjunto opcional de parâmetros definindo +// raio de cada canto +// Desenha um retângulo com {a, b} como coordenada superior esquerda e c e d como largura +// e altura respectivamente. + +// Quad +quad(x, y, x2, y2, x3, y3, x4, y4); +// Desenha um quadrilátero com parâmetros que definem as coordenadas de cada canto +// ponto. + +// Elipse +ellipse(x, y, largura, altura); +// Desenha um eclipse no ponto {x, y} com largura e altura especificadas. + +// Arco +arc(x, y, largura, altura, inicio, fim, [modo]); +// Enquanto os primeiros quatro parâmetros são autoexplicativos, +// início e fim definem os ângulos que o arco começa e termina (em radianos). +// O parâmetro opcional [mode] define o preenchimento; +// PIE dá o contorno de torta, CHORD dá o contorno reto e OPEN é como +// CHORD porém sem contorno + +// Curvas +// O processamento fornece duas implementações de curvas; usando curve() e bezier(). +// Como pretendo manter isso simples, não vou discutir mais detalhes. +// No entanto, se você quiser implementá-lo em seu sketch, aqui estão as referências: +// (https://processing.org/reference/curve_.html) +// (https://processing.org/reference/bezier_.html) + +// Formas 3D + +// espaço 3D +pode ser configurado definindo "P3D" para o parâmetro do renderizador no +// método size(). +size(largura, altura, P3D); +// No espaço 3D, você terá que traduzir para a coordenada específica para +// renderiza as formas 3D. + +// Caixa +box(tamanho); // Cubo com o mesmo comprimento definido pelo tamanho +caixa(w, h, d); // Caixa com largura, altura e profundidade definidas separadamente + +// Esfera +sphere(raio); // Seu tamanho é definido usando o parâmetro raio +// O mecanismo por trás da renderização das esferas é implementado por triângulos em mosaico. +// Dito isso, o nível de detalhe sendo renderizado é controlado pela função +// sphereDetail(res) +// Mais informações aqui: (https://processing.org/reference/sphereDetail_.html) + +// Formas irregulares +// E se você quiser desenhar algo que não foi disponibilizado pelo Processing +// funções? +// Você pode usar beginShape(), endShape(), vertex(x,y) para definir formas por +// especificando cada ponto. Mais informações aqui: +// (https://processing.org/reference/beginShape_.html) +// Você também pode usar formas personalizadas usando a classe PShape: +// (https://processing.org/reference/PShape.html) + +/* --------------- + Transformações + --------------- +*/ + +// As transformações são particularmente úteis para acompanhar o espaço de coordenadas +// e os vértices das formas que você desenhou. Particularmente; +// métodos de pilha de matrizes; pushMatrix(), popMatrix() e translate(x,y) +pushMatriz(); // Salva o sistema de coordenadas atual na pilha +// ... aplique todas as transformações aqui ... +popMatriz(); // Restaura o sistema de coordenadas salvo +// Usando-os, o sistema de coordenadas pode ser preservado e visualizado sem +// causar qualquer conflito. + +// Traduzir +translate(x,y); // Traduz para o ponto{x, y} ou seja - configurando a origem para esse ponto +translate(x, y, z); // Contraparte 3D da função + +// Rotacionar +rotate(ângulo); // Gira a quantidade especificada pelo parâmetro ângulo +// Possui 3 contrapartes 3D para realizar a rotação, uma para cada dimensão: rotateX(ângulo), rotateY(ângulo), rotateZ(ângulo) + +// Escala +scale(s); // Dimensiona o sistema de coordenadas expandindo ou contraindo-o. + +/* -------------------- + Estilo e texturas + -------------------- +*/ + +// Cores +// Como discuti anteriormente, a cor de fundo pode ser configurada usando a função +// background(). Você pode definir a cor de um objeto de antemão e depois +// passar para a função como um argumento. +color c = cor(255, 255, 255); // BRANCO! +// Por padrão, o Processing usa o esquema de cores RGB, mas pode ser configurado para +// HSB usando colorMode(). Leia mais aqui: +// (https://processing.org/reference/colorMode_.html) +background(c); // Até agora, a cor de fundo deve ser branca. +// Você pode usar a função fill() para selecionar a cor para preencher as formas. +// Tem que ser configurado antes de você começar a desenhar formas para que as cores fiquem +// aplicadas. +fill(color(0, 0, 0)); +// Se você quiser apenas colorir os contornos das formas, você pode usar +// função stroke(). +stroke(255, 255, 0, 200); // cor do traço definida para amarelo com transparência +// definido para um valor menor. + +// Imagens +// O processamento pode renderizar imagens e usá-las de várias maneiras. Principalmente armazenado como +// Tipo de dados PImage. +filter(sombreador); // O processamento suporta várias funções de filtro para manipulação de imagens. +texture(imagem); // PImage pode ser passado em argumentos para mapeamento de textura das formas. +``` + +Se você quiser levar as coisas adiante, há mais coisas que o Processing tem o poder de fazer. +Renderizar modelos, shaders e outros enfeites. Há muito para se cobrir em uma +documentação curta, então vou deixá-los aqui. Se você se interessar, +por favor verifique as referências. + +``` +// Antes de prosseguirmos, vou falar um pouco mais sobre como importar bibliotecas +// para que você possa estender a funcionalidade do Processing para outros horizontes. + +/* ------- + Importações + ------- +*/ + +// As possibilidades do Processing pode ser extendidas ainda mais quando importamos bibliotecas +// e pacotes em nossos esboços. +// A instrução de importação pode ser escrita como abaixo na parte superior do código-fonte. +import processing.something.*; +``` + +## VAC? + +Vamos ao código? Vamos sujar as mãos! + +Vamos ver um exemplo do openprocessing para visualizar o quanto o Processing é +capaz de fazer com poucas linhas de código. + +Copie o código abaixo em seu IDE do Processing e veja a mágica. + +``` +// Isenção de responsabilidade: eu não escrevi este programa porque atualmente estou ocupado com meu +// estágio e este sketch é adaptado do openprocessing pois mostra +// algo legal com um código simples. +// Recuperado de: (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; i30) { + pushMatrix(); + translate(0, -30); + rotate(theta); + branch(len); + popMatrix(); + + pushMatrix(); + translate(0, -30); + rotate(-theta); + branch(len); + popMatrix(); + + } +} +``` + +O processamento é fácil de aprender e é particularmente útil para criar +conteúdo (mesmo em 3D) sem ter que digitar muitos códigos. É tão simples +que você pode ler o código e ter uma ideia aproximada do fluxo do programa. + +No entanto, isso não se aplica quando você introduz bibliotecas externas, pacotes +e até mesmo suas próprias aulas. (Confie em mim! O processamento de projetos pode ficar realmente monstruoso...) + +## Alguns recursos úteis + + - [Site de processamento](http://processing.org) + - [Processando esboços](http://openprocessing.org) \ No newline at end of file -- cgit v1.2.3 From 6574a372795ac53147c415ba9511ed88240cbb9b Mon Sep 17 00:00:00 2001 From: Kemel Zaidan Date: Thu, 27 Oct 2022 16:01:30 -0300 Subject: fixing some typos after review --- pt-br/processing-pt.html.markdown | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/pt-br/processing-pt.html.markdown b/pt-br/processing-pt.html.markdown index dab5a98d..a511000b 100644 --- a/pt-br/processing-pt.html.markdown +++ b/pt-br/processing-pt.html.markdown @@ -45,7 +45,7 @@ compilar e executar os scripts. // Observação! A sintaxe é muito semelhante à do C++. void setup() { // Isso imprime a saída clássica "Hello World!" para o console quando executado. - println("Olá Mundo!"); // Outra linguagem com cilada para ponto-e-vígula, não é? + println("Olá Mundo!"); // Outra linguagem com cilada para ponto e vírgula, não é? } // Normalmente, colocamos todos os códigos estáticos dentro do método setup() como o próprio nome @@ -105,7 +105,7 @@ string stringExemplo = "Olá, Processing!"; // String também pode ser construída a partir de um array de tipos de dados char. Nós vamos // discutir array muito em breve. char fonte = {'H', 'E', 'L', 'L', 'O'}; -string stringDeFonte = new String(source); // HELLO +String stringDeFonte = new String(source); // HELLO // Como em Java, strings podem ser concatenadas usando o operador "+". print("Olá " + "Mundo!"); // Olá Mundo! @@ -145,8 +145,8 @@ UmaClasseQualquer meuObjetoInstanciado = new UmaClasseQualquer(); 2 - 1 // 1 2 * 3 // 6 3/2 // 1 -3,0 / 2 // 1,5 -3,0% 2 // 1,0 +3.0 / 2 // 1.5 +3.0% 2 // 1.0 // O Processing também vem com um conjunto de funções que simplificam operações matemáticas. float f = sq(3); // f = 9.0 @@ -180,15 +180,15 @@ float um = sin(PI/2); // um = 1.0 // Declarações Condicionais // Instruções If - A mesma sintaxe das instruções if em Java. -if (autor.getAppearance().equals("quente")) { - print("Narcisismo no seu melhor!"); -} senão { +if (author.getAppearance().equals("quente")) { + print("Narcisismo no máximo!"); +} else { // Você pode verificar outras condições aqui. print("Algo está realmente errado aqui!"); } // Um ​​atalho para instruções if-else também pode ser usado. int = 3; -Valor da string = (i > 5) ? "Grande" : "Pequena"; // "Pequena" +String valor = (i > 5) ? "Grande" : "Pequena"; // "Pequena" // A estrutura switch-case pode ser usada para verificar várias condições de forma concisa. // É importante usar a instrução break. Se a instrução `break` @@ -260,7 +260,7 @@ triangle(x1, y1, x2, y2, x3, y3); // Retângulo rect(a, b, c, d, [r]); // Com parâmetro opcional definindo o raio de todos os cantos -rect(a, b, c, d, [tl, tr, br, bl]); // Com conjunto opcional de parâmetros definindo +rect(a, b, c, d, [te, td, bd, be]); // Com conjunto opcional de parâmetros definindo // raio de cada canto // Desenha um retângulo com {a, b} como coordenada superior esquerda e c e d como largura // e altura respectivamente. @@ -374,7 +374,7 @@ texture(imagem); // PImage pode ser passado em argumentos para mapeamento de tex ``` Se você quiser levar as coisas adiante, há mais coisas que o Processing tem o poder de fazer. -Renderizar modelos, shaders e outros enfeites. Há muito para se cobrir em uma +Renderizar modelos, shaders e outros efeitos. Há muito para se cobrir em uma documentação curta, então vou deixá-los aqui. Se você se interessar, por favor verifique as referências. @@ -387,10 +387,10 @@ por favor verifique as referências. ------- */ -// As possibilidades do Processing pode ser extendidas ainda mais quando importamos bibliotecas +// As possibilidades do Processing pode ser estendidas ainda mais quando importamos bibliotecas // e pacotes em nossos esboços. // A instrução de importação pode ser escrita como abaixo na parte superior do código-fonte. -import processing.something.*; +import processing.algumacoisa.*; ``` ## VAC? @@ -465,5 +465,5 @@ e até mesmo suas próprias aulas. (Confie em mim! O processamento de projetos p ## Alguns recursos úteis - - [Site de processamento](http://processing.org) - - [Processando esboços](http://openprocessing.org) \ No newline at end of file + - [Site do Processing](http://processing.org) + - [Sketches em Processing](http://openprocessing.org) \ No newline at end of file -- cgit v1.2.3 From 6e3ca550f9b6561a193fc95fb40d84b976f9dd01 Mon Sep 17 00:00:00 2001 From: Kemel Zaidan Date: Thu, 27 Oct 2022 17:10:12 -0300 Subject: fixes the texts which were exceeding 80 collumns --- pt-br/processing-pt.html.markdown | 156 ++++++++++++++++++++------------------ 1 file changed, 83 insertions(+), 73 deletions(-) diff --git a/pt-br/processing-pt.html.markdown b/pt-br/processing-pt.html.markdown index a511000b..229aec07 100644 --- a/pt-br/processing-pt.html.markdown +++ b/pt-br/processing-pt.html.markdown @@ -12,11 +12,12 @@ lang: pt-br ## Introdução Processing é uma linguagem de programação para criação de artes digitais e -conteúdo multimídia, permitindo que não programadores aprendam os fundamentos da -programação computacional em um contexto visual. +conteúdo multimídia, permitindo que não programadores aprendam os fundamentos +da programação computacional em um contexto visual. Embora a linguagem seja baseada na linguagem Java, sua sintaxe foi amplamente -influenciado por ambas as sintaxes Java e Javascript. [Veja mais aqui](https://processing.org/reference/) +influenciado por ambas as sintaxes Java e Javascript. +[Veja mais aqui](https://processing.org/reference/) A linguagem é tipada estaticamente e também vem com a sua IDE oficial para compilar e executar os scripts. @@ -31,7 +32,8 @@ compilar e executar os scripts. /* Como o Processing é baseado em Java, - a sintaxe para seus comentários é a mesma do Java (como você deve ter notado acima)! + a sintaxe para seus comentários é a mesma do Java (como você deve ter notado + acima)! Comentários de várias linhas são agrupados como visto aqui. */ @@ -40,25 +42,26 @@ compilar e executar os scripts. --------------------------------------- */ -// No Processing, o ponto de entrada do programa é uma função chamada setup() com um -// tipo de retorno void. +// No Processing, o ponto de entrada do programa é uma função chamada setup() +// com um tipo de retorno void. // Observação! A sintaxe é muito semelhante à do C++. void setup() { - // Isso imprime a saída clássica "Hello World!" para o console quando executado. - println("Olá Mundo!"); // Outra linguagem com cilada para ponto e vírgula, não é? + // Isso imprime a saída clássica "Hello World!" no console quando executado. + println("Olá Mundo!"); // Outra linguagem cilada para ponto e vírgula, não é? } -// Normalmente, colocamos todos os códigos estáticos dentro do método setup() como o próprio nome -// sugere, uma vez que é executado apenas uma vez. +// Normalmente, colocamos todos os códigos estáticos dentro do método setup() +// como o próprio nome sugere, uma vez que é executado apenas uma vez. // Pode variar da definição das cores de fundo, ou o tamanho da tela. background(color); //define a cor do fundo size(largura,altura,[renderizador]); // define o tamanho da tela com parâmetro // opcional para definir o renderizador // Você verá mais sobre isso ao longo deste documento. -// Se você deseja executar os códigos indefinidamente, eles devem ser colocados dentro do método draw() -// draw() deve existir caso você queira que o código seja executado continuamente e, obviamente, -// só pode haver um método draw(). +// Se você deseja executar os códigos indefinidamente, eles devem ser colocados +// dentro do método draw() +// draw() deve existir caso você queira que o código seja executado +// continuamente e, obviamente, só pode haver um método draw(). int = 0; void draw(){ // Este bloco de código faz um loop para sempre até parar @@ -92,40 +95,43 @@ double valorDouble = 1,12345D; // Double (números de ponto flutuante de 64 bits // NOTA! // Embora os tipos de dados "long" e "double" funcionem na linguagem, // funções do Processing não usam esses tipos de dados, portanto -// eles precisam ser convertidos em tipos de dados "int" e "float", respectivamente, -// usando a sintaxe (int) e (float) antes de passar para uma função. +// eles precisam ser convertidos em tipos de dados "int" e "float", +// respectivamente, usando a sintaxe (int) e (float) antes de passar para uma +// função. -// Existem vários tipos de dados compostos que estão disponíveis por padrão para uso -// no Processing. +// Existem vários tipos de dados compostos que estão disponíveis por padrão para +// uso no Processing. // Primeiramente, farei um resumo dos mais usados ​​para economizar tempo. // String -// Enquanto o tipo de dados char usa '', o tipo de dados String usa "" - aspas duplas. +// Enquanto o tipo de dados char usa '', o tipo de dados String usa "" - aspas +// duplas. string stringExemplo = "Olá, Processing!"; -// String também pode ser construída a partir de um array de tipos de dados char. Nós vamos -// discutir array muito em breve. +// String também pode ser criada a partir de um array de tipos de dados char. +// Nós vamos discutir array muito em breve. char fonte = {'H', 'E', 'L', 'L', 'O'}; String stringDeFonte = new String(source); // HELLO // Como em Java, strings podem ser concatenadas usando o operador "+". print("Olá " + "Mundo!"); // Olá Mundo! // Array -// Arrays em Processing podem conter quaisquer tipos de dados, incluindo os próprios objetos. -// Como os arrays são semelhantes aos objetos, eles devem ser criados com a palavra-chave -// "new". +// Arrays em Processing podem conter quaisquer tipos de dados, incluindo os +// próprios objetos. Como os arrays são semelhantes aos objetos, eles devem +// ser criados com a palavra-chave "new". int[] arrayInt = new int[5]; int[] arrayIntComValores ​​= {1, 2, 3}; // Você também pode preencher com dados. // Lista de Arrays -// As funções são semelhantes às do array; arraylists podem conter qualquer tipo de dados. -// A única diferença é que as listas de matrizes são redimensionadas dinamicamente, pois é uma forma de -// implementação de matriz redimensionável da interface "List" do Java . +// As funções são semelhantes às do array; arraylists podem conter qualquer +// tipo de dados. A única diferença é que as listas de matrizes são +// redimensionadas dinamicamente, pois é uma forma de implementação de matriz +// redimensionável da interface "List" do Java . ArrayList intArrayList = new ArrayList(); // Objeto // Como é baseado em Java, o Processing suporta programação orientada a objetos. -// Isso significa que você pode basicamente definir quaisquer tipos de dados de sua preferência e manipulá-los -// para suas necessidades. +// Isso significa que você pode basicamente definir quaisquer tipos de dados de +// sua preferência e manipulá-los para suas necessidades. // Claro, uma classe tem que ser definida antes para o objeto que você quer. // Formato --> NomeClasse NameInstancia UmaClasseQualquer meuObjeto // então instancia mais tarde @@ -133,7 +139,7 @@ UmaClasseQualquer meuObjeto // então instancia mais tarde UmaClasseQualquer meuObjetoInstanciado = new UmaClasseQualquer(); // O Processing surge com mais coleções (ex. - Dicionários e Listas) por -// padrão, por uma questão de simplicidade, vou deixá-los fora de discussão aqui. +// padrão, por uma questão de simplicidade, vou deixá-los fora da discussão aqui. /* ------------ Matemática @@ -148,7 +154,8 @@ UmaClasseQualquer meuObjetoInstanciado = new UmaClasseQualquer(); 3.0 / 2 // 1.5 3.0% 2 // 1.0 -// O Processing também vem com um conjunto de funções que simplificam operações matemáticas. +// O Processing também vem com um conjunto de funções que simplificam operações +// matemáticas. float f = sq(3); // f = 9.0 float p = pow(3, 3); // p = 27.0 int a = abs(-13); // a = 13 @@ -160,18 +167,18 @@ float sr = sqrt(25); // sr = 5.0 // O Processing fornece uma maneira fácil de implementar vetores em seu ambiente // usando a classe PVector. Ela pode descrever um vetor bi ou tridimensional e // vem com um conjunto de métodos que são úteis para operações com matrizes. -// Você pode encontrar mais informações sobre a classe PVector e suas funções aqui. -// (https://processing.org/reference/PVector.html) +// Você pode encontrar mais informações sobre a classe PVector e suas funções +// aqui. (https://processing.org/reference/PVector.html) // Trigonometria -// O processamento também suporta operações trigonométricas fornecendo um conjunto de -// funções. sin(), cos(), tan(), asin(), acos(), atan() e também degrees() -// e radians() para conversão conveniente. -// No entanto, essas funções usam o ângulo em radianos como parâmetro, então é necessário -// converter previamente. +// O processamento também suporta operações trigonométricas fornecendo um +// conjunto de funções. sin(), cos(), tan(), asin(), acos(), atan() e também +// degrees() e radians() para conversão conveniente. +// No entanto, essas funções usam o ângulo em radianos como parâmetro, então é +// necessário converter previamente. float um = sin(PI/2); // um = 1.0 -// Como você deve ter notado, existe um conjunto de constantes para usos trigonométricos; -// PI, HALF_PI, QUARTER_PI e assim por diante... +// Como você deve ter notado, existe um conjunto de constantes para usos +// trigonométricos; PI, HALF_PI, QUARTER_PI e assim por diante... /* ------------- Controle de fluxo @@ -190,9 +197,10 @@ if (author.getAppearance().equals("quente")) { int = 3; String valor = (i > 5) ? "Grande" : "Pequena"; // "Pequena" -// A estrutura switch-case pode ser usada para verificar várias condições de forma concisa. -// É importante usar a instrução break. Se a instrução `break` -// não existe o programa executa todos os casos a seguir após um caso ser verdadeiro. +// A estrutura switch-case pode ser usada para verificar várias condições de +// forma concisa. É importante usar a instrução break. Se a instrução `break` +// não existe o programa executa todos os casos a seguir após um caso ser +// verdadeiro. int valor = 2; switch(valor) { case 0: @@ -215,7 +223,8 @@ for(int i = 0; i < 5; i++){ print(i); // imprime de 0 a 4 } -// Declarações While - Novamente, nada de novo se você estiver familiarizado com a sintaxe Java. +// Declarações While - Novamente, nada de novo se você estiver familiarizado com +// a sintaxe Java. int j = 3; while(j > 0) { print(j); @@ -223,7 +232,8 @@ while(j > 0) { } // loop()| noLoop() | redraw() | exit() -// Estas são mais funções específicas do Processing para configurar o fluxo do programa. +// Estas são mais funções específicas do Processing para configurar o fluxo do +// programa. loop(); // permite que o método draw() seja executado para sempre enquanto noLoop(); // só permite que ele seja executado uma vez. redraw(); // executa o método draw() mais uma vez. @@ -283,10 +293,10 @@ arc(x, y, largura, altura, inicio, fim, [modo]); // CHORD porém sem contorno // Curvas -// O processamento fornece duas implementações de curvas; usando curve() e bezier(). -// Como pretendo manter isso simples, não vou discutir mais detalhes. -// No entanto, se você quiser implementá-lo em seu sketch, aqui estão as referências: -// (https://processing.org/reference/curve_.html) +// O processamento fornece duas implementações de curvas; usando curve() e +// bezier(). Como pretendo manter isso simples, não vou discutir mais detalhes. +// No entanto, se você quiser implementá-lo em seu sketch, aqui estão as +// referências: (https://processing.org/reference/curve_.html) // (https://processing.org/reference/bezier_.html) // Formas 3D @@ -300,13 +310,13 @@ size(largura, altura, P3D); // Caixa box(tamanho); // Cubo com o mesmo comprimento definido pelo tamanho -caixa(w, h, d); // Caixa com largura, altura e profundidade definidas separadamente +box(w, h, d); // Caixa com largura, altura e profundidade definidas separadamente // Esfera sphere(raio); // Seu tamanho é definido usando o parâmetro raio -// O mecanismo por trás da renderização das esferas é implementado por triângulos em mosaico. -// Dito isso, o nível de detalhe sendo renderizado é controlado pela função -// sphereDetail(res) +// O mecanismo por trás da renderização das esferas é implementado por +// triângulos em mosaico. Dito isso, o nível de detalhe sendo renderizado é +// controlado pela função sphereDetail(res) // Mais informações aqui: (https://processing.org/reference/sphereDetail_.html) // Formas irregulares @@ -323,8 +333,8 @@ sphere(raio); // Seu tamanho é definido usando o parâmetro raio --------------- */ -// As transformações são particularmente úteis para acompanhar o espaço de coordenadas -// e os vértices das formas que você desenhou. Particularmente; +// As transformações são particularmente úteis para acompanhar o espaço de +// coordenadas e os vértices das formas que você desenhou. Particularmente; // métodos de pilha de matrizes; pushMatrix(), popMatrix() e translate(x,y) pushMatriz(); // Salva o sistema de coordenadas atual na pilha // ... aplique todas as transformações aqui ... @@ -338,7 +348,8 @@ translate(x, y, z); // Contraparte 3D da função // Rotacionar rotate(ângulo); // Gira a quantidade especificada pelo parâmetro ângulo -// Possui 3 contrapartes 3D para realizar a rotação, uma para cada dimensão: rotateX(ângulo), rotateY(ângulo), rotateZ(ângulo) +// Possui 3 contrapartes 3D para realizar a rotação, uma para cada dimensão: +// rotateX(ângulo), rotateY(ângulo), rotateZ(ângulo) // Escala scale(s); // Dimensiona o sistema de coordenadas expandindo ou contraindo-o. @@ -349,17 +360,17 @@ scale(s); // Dimensiona o sistema de coordenadas expandindo ou contraindo-o. */ // Cores -// Como discuti anteriormente, a cor de fundo pode ser configurada usando a função -// background(). Você pode definir a cor de um objeto de antemão e depois +// Como discuti anteriormente, a cor de fundo pode ser configurada usando a +// função background(). Você pode definir a cor de um objeto de antemão e depois // passar para a função como um argumento. color c = cor(255, 255, 255); // BRANCO! -// Por padrão, o Processing usa o esquema de cores RGB, mas pode ser configurado para -// HSB usando colorMode(). Leia mais aqui: +// Por padrão, o Processing usa o esquema de cores RGB, mas pode ser configurado +// para HSB usando colorMode(). Leia mais aqui: // (https://processing.org/reference/colorMode_.html) background(c); // Até agora, a cor de fundo deve ser branca. // Você pode usar a função fill() para selecionar a cor para preencher as formas. -// Tem que ser configurado antes de você começar a desenhar formas para que as cores fiquem -// aplicadas. +// Tem que ser configurado antes de você começar a desenhar formas para que as +// cores fiquem aplicadas. fill(color(0, 0, 0)); // Se você quiser apenas colorir os contornos das formas, você pode usar // função stroke(). @@ -367,16 +378,14 @@ stroke(255, 255, 0, 200); // cor do traço definida para amarelo com transparên // definido para um valor menor. // Imagens -// O processamento pode renderizar imagens e usá-las de várias maneiras. Principalmente armazenado como -// Tipo de dados PImage. +// O processamento pode renderizar imagens e usá-las de várias maneiras. +// Principalmente armazenado como Tipo de dados PImage. filter(sombreador); // O processamento suporta várias funções de filtro para manipulação de imagens. texture(imagem); // PImage pode ser passado em argumentos para mapeamento de textura das formas. ``` -Se você quiser levar as coisas adiante, há mais coisas que o Processing tem o poder de fazer. -Renderizar modelos, shaders e outros efeitos. Há muito para se cobrir em uma -documentação curta, então vou deixá-los aqui. Se você se interessar, -por favor verifique as referências. +Se você quiser levar as coisas adiante, há mais coisas que o Processing tem o poder de fazer. Renderizar modelos, shaders e outros efeitos. Há muito para se cobrir em uma +documentação curta, então vou deixá-los aqui. Se você se interessar, por favor verifique as referências. ``` // Antes de prosseguirmos, vou falar um pouco mais sobre como importar bibliotecas @@ -387,9 +396,10 @@ por favor verifique as referências. ------- */ -// As possibilidades do Processing pode ser estendidas ainda mais quando importamos bibliotecas -// e pacotes em nossos esboços. -// A instrução de importação pode ser escrita como abaixo na parte superior do código-fonte. +// As possibilidades do Processing pode ser estendidas ainda mais quando +// importamos bibliotecas e pacotes em nossos esboços. +// A instrução de importação pode ser escrita como abaixo na parte superior +// do código-fonte. import processing.algumacoisa.*; ``` @@ -403,9 +413,9 @@ capaz de fazer com poucas linhas de código. Copie o código abaixo em seu IDE do Processing e veja a mágica. ``` -// Isenção de responsabilidade: eu não escrevi este programa porque atualmente estou ocupado com meu -// estágio e este sketch é adaptado do openprocessing pois mostra -// algo legal com um código simples. +// Isenção de responsabilidade: eu não escrevi este programa porque atualmente +// estou ocupado com meu estágio e este sketch é adaptado do openprocessing pois +// mostra algo legal com um código simples. // Recuperado de: (https://www.openprocessing.org/sketch/559769) float theta; -- cgit v1.2.3 From 9912e4294585cf717e13cb874dcad298d140af6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mr=20Alexandre=20ELIS=C3=89?= Date: Sun, 30 Oct 2022 22:15:26 -0400 Subject: Hi, I might have found a typo (#4528) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hi, French is my native language and I think I might have found a typo regarding a pronoun in French in the original text it says 'la première élément' but seems to have a typo it should be 'le premier élément'. Just trying to be helpful. Enjoy your day. BTW I like your awesome website https://learnxinyminutes.com thanks for this cool initiative. --- fr-fr/set-theory-fr.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fr-fr/set-theory-fr.html.markdown b/fr-fr/set-theory-fr.html.markdown index 543bd98b..d1ac2711 100644 --- a/fr-fr/set-theory-fr.html.markdown +++ b/fr-fr/set-theory-fr.html.markdown @@ -125,7 +125,7 @@ A △ B = (A \ B) ∪ (B \ A) ``` ### Produit cartésien -Le produit cartésien de deux ensembles `A` et `B` est l'ensemble contenant tous les couples dont la première élément appartient à `A` et la deuxième à `B`. +Le produit cartésien de deux ensembles `A` et `B` est l'ensemble contenant tous les couples dont le premier élément appartient à `A` et le deuxième à `B`. ``` A × B = { (x, y) | x ∈ A, y ∈ B } -- cgit v1.2.3 From edada55eb0a05c8ccb0e39ba6d1bc74a3decb180 Mon Sep 17 00:00:00 2001 From: John Paul Wohlscheid Date: Sat, 5 Nov 2022 23:32:45 -0400 Subject: fixed spelling errors --- ldpl.html.markdown | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ldpl.html.markdown b/ldpl.html.markdown index 86603d94..449c8670 100644 --- a/ldpl.html.markdown +++ b/ldpl.html.markdown @@ -3,6 +3,7 @@ language: LDPL filename: learnLDPL.ldpl contributors: - ["Martín del Río", "https://github.com/lartu"] + - ["John Paul Wohlscheid", "https://github.com/JohnBlood"] --- **LDPL** is a powerful, C++ transpiled, open-source programming language designed @@ -68,7 +69,7 @@ else if myMap:"someIndex" is not equal to 45 then else display "Else!" crlf end if -# Valid LDPL comparisson operators are +# Valid LDPL comparison operators are # - IS EQUAL TO # - IS NOT EQUAL TO # - IS LESS THAN @@ -123,8 +124,8 @@ get random in myNumber # get a random number between 0 and 1 # files, are divided in sections. The sections found in sub-procedures are # the PARAMETERS section, the LOCAL DATA section and the PROCEDURE section. # All sections except the PROCEDURE section can be skipped if they aren't -# used. If no PARAMTERS nor LOCAL DATA sections are used, the PROCEDURE -# keyword may be omited. +# used. If no PARAMETERS nor LOCAL DATA sections are used, the PROCEDURE +# keyword may be omitted. sub myFunction parameters: a is number # LDPL is pass by reference -- cgit v1.2.3 From 0dcfdfb4b4fe27dce599b10f915a55d162e6496c Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Tue, 8 Nov 2022 12:50:57 +0100 Subject: remove overly long lines by additional line breaks The threshold of a line considered as too long is 80 characters per line. Changes introduced only alter the use of line breaks. --- python.html.markdown | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/python.html.markdown b/python.html.markdown index 687529b5..72dd45a6 100644 --- a/python.html.markdown +++ b/python.html.markdown @@ -13,11 +13,13 @@ contributors: filename: learnpython.py --- -Python was created by Guido van Rossum in the early 90s. It is now one of the most popular -languages in existence. I fell in love with Python for its syntactic clarity. It's basically -executable pseudocode. +Python was created by Guido van Rossum in the early 90s. It is now one of the +most popular languages in existence. I fell in love with Python for its +syntactic clarity. It's basically executable pseudocode. -Note: This article applies to Python 3 specifically. Check out [here](http://learnxinyminutes.com/docs/pythonlegacy/) if you want to learn the old Python 2.7 +Note: This article applies to Python 3 specifically. Check out +[here](http://learnxinyminutes.com/docs/pythonlegacy/) if you want to learn the +old Python 2.7 ```python @@ -97,8 +99,9 @@ bool(set()) # => False bool(4) # => True bool(-6) # => True -# Using boolean logical operators on ints casts them to booleans for evaluation, but their non-cast value is returned -# Don't mix up with bool(ints) and bitwise and/or (&,|) +# Using boolean logical operators on ints casts them to booleans for evaluation, +# but their non-cast value is returned. Don't mix up with bool(ints) and bitwise +# and/or (&,|) bool(0) # => False bool(2) # => True 0 and 2 # => 0 @@ -348,7 +351,7 @@ del filled_dict["one"] # Removes the key "one" from filled dict # Sets store ... well sets empty_set = set() -# Initialize a set with a bunch of values. Yeah, it looks a bit like a dict. Sorry. +# Initialize a set with a bunch of values. some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4} # Similar to keys of a dictionary, elements of a set have to be immutable. @@ -533,8 +536,8 @@ our_iterable[1] # Raises a TypeError # An iterable is an object that knows how to create an iterator. our_iterator = iter(our_iterable) -# Our iterator is an object that can remember the state as we traverse through it. -# We get the next object with "next()". +# Our iterator is an object that can remember the state as we traverse through +# it. We get the next object with "next()". next(our_iterator) # => "one" # It maintains state as we iterate. @@ -719,8 +722,8 @@ class Human: # Note that the double leading and trailing underscores denote objects # or attributes that are used by Python but that live in user-controlled # namespaces. Methods(or objects or attributes) like: __init__, __str__, - # __repr__ etc. are called special methods (or sometimes called dunder methods) - # You should not invent such names on your own. + # __repr__ etc. are called special methods (or sometimes called dunder + # methods). You should not invent such names on your own. def __init__(self, name): # Assign the argument to the instance's name attribute self.name = name @@ -811,8 +814,8 @@ if __name__ == '__main__': # "species", "name", and "age", as well as methods, like "sing" and "grunt" # from the Human class, but can also have its own unique properties. -# To take advantage of modularization by file you could place the classes above in their own files, -# say, human.py +# To take advantage of modularization by file you could place the classes above +# in their own files, say, human.py # To import functions from other files use the following format # from "filename-without-extension" import "function-or-class" -- cgit v1.2.3 From 3d0ea351cb733f081d63aff337544cd1bcba41e4 Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Tue, 8 Nov 2022 13:33:15 +0100 Subject: remove overly long lines by edit of content Light rephrasing to stay within the constraint of 80 chars/line. The cross links at the end of the document are not affected. --- python.html.markdown | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/python.html.markdown b/python.html.markdown index 72dd45a6..2247f263 100644 --- a/python.html.markdown +++ b/python.html.markdown @@ -155,10 +155,10 @@ b == a # => True, a's and b's objects are equal # You can find the length of a string len("This is a string") # => 16 -# You can also format using f-strings or formatted string literals (in Python 3.6+) +# Since Python 3.6, you can use f-strings or formatted string literals. name = "Reiko" f"She said her name is {name}." # => "She said her name is Reiko" -# You can basically put any Python expression inside the braces and it will be output in the string. +# Any valid Python expression inside these braces is returned to the string. f"{name} is {len(name)} characters long." # => "Reiko is 5 characters long." # None is an object @@ -297,7 +297,7 @@ filled_dict = {"one": 1, "two": 2, "three": 3} # Note keys for dictionaries have to be immutable types. This is to ensure that # the key can be converted to a constant hash value for quick look-ups. # Immutable types include ints, floats, strings, tuples. -invalid_dict = {[1,2,3]: "123"} # => Raises a TypeError: unhashable type: 'list' +invalid_dict = {[1,2,3]: "123"} # => Yield a TypeError: unhashable type: 'list' valid_dict = {(1,2,3):[1,2,3]} # Values can be of any type, however. # Look up values with [] @@ -457,8 +457,7 @@ for i in range(4, 8, 2): print(i) """ -To loop over a list, and retrieve both the index and the value of each item in the list -prints: +Loop over a list to retrieve both the index and the value of each list item: 0 dog 1 cat 2 mouse @@ -485,10 +484,11 @@ try: # Use "raise" to raise an error raise IndexError("This is an index error") except IndexError as e: - pass # Pass is just a no-op. Usually you would do recovery here. + pass # Refrain from this, provide a recovery (next example). except (TypeError, NameError): - pass # Multiple exceptions can be handled together, if required. -else: # Optional clause to the try/except block. Must follow all except blocks + pass # Multiple exceptions can be processed jointly. +else: # Optional clause to the try/except block. Must follow + # all except blocks. print("All good!") # Runs only if the code in try raises no exceptions finally: # Execute under all circumstances print("We can clean up resources here") @@ -524,7 +524,8 @@ print(contents) filled_dict = {"one": 1, "two": 2, "three": 3} our_iterable = filled_dict.keys() -print(our_iterable) # => dict_keys(['one', 'two', 'three']). This is an object that implements our Iterable interface. +print(our_iterable) # => dict_keys(['one', 'two', 'three']). This is an object + # that implements our Iterable interface. # We can loop over it. for i in our_iterable: @@ -544,7 +545,8 @@ next(our_iterator) # => "one" next(our_iterator) # => "two" next(our_iterator) # => "three" -# After the iterator has returned all of its data, it raises a StopIteration exception +# After the iterator has returned all of its data, it raises a +# StopIteration exception next(our_iterator) # Raises StopIteration # We can also loop over it, in fact, "for" does this implicitly! @@ -552,7 +554,7 @@ our_iterator = iter(our_iterable) for i in our_iterator: print(i) # Prints one, two, three -# You can grab all the elements of an iterable or iterator by calling list() on it. +# You can grab all the elements of an iterable or iterator by call of list(). list(our_iterable) # => Returns ["one", "two", "three"] list(our_iterator) # => Returns [] because state is saved @@ -602,9 +604,9 @@ all_the_args(1, 2, a=3, b=4) prints: # Use * to expand tuples and use ** to expand kwargs. args = (1, 2, 3, 4) kwargs = {"a": 3, "b": 4} -all_the_args(*args) # equivalent to all_the_args(1, 2, 3, 4) -all_the_args(**kwargs) # equivalent to all_the_args(a=3, b=4) -all_the_args(*args, **kwargs) # equivalent to all_the_args(1, 2, 3, 4, a=3, b=4) +all_the_args(*args) # equivalent: all_the_args(1, 2, 3, 4) +all_the_args(**kwargs) # equivalent: all_the_args(a=3, b=4) +all_the_args(*args, **kwargs) # equivalent: all_the_args(1, 2, 3, 4, a=3, b=4) # Returning multiple values (with tuple assignments) def swap(x, y): @@ -614,7 +616,7 @@ def swap(x, y): x = 1 y = 2 x, y = swap(x, y) # => x = 2, y = 1 -# (x, y) = swap(x,y) # Again parenthesis have been excluded but can be included. +# (x, y) = swap(x,y) # Again the use of parenthesis is optional. # global scope x = 5 @@ -662,7 +664,7 @@ list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3] list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [6, 7] # We can use list comprehensions for nice maps and filters -# List comprehension stores the output as a list which can itself be a nested list +# List comprehension stores the output as a list (which itself may be nested). [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] @@ -777,7 +779,7 @@ if __name__ == '__main__': i.say("hi") # "Ian: hi" j = Human("Joel") j.say("hello") # "Joel: hello" - # i and j are instances of type Human, or in other words: they are Human objects + # i and j are instances of type Human; i.e., they are Human objects. # Call our class method i.say(i.get_species()) # "Ian: H. sapiens" @@ -939,8 +941,8 @@ class Batman(Superhero, Bat): # However we are dealing with multiple inheritance here, and super() # only works with the next base class in the MRO list. # So instead we explicitly call __init__ for all ancestors. - # The use of *args and **kwargs allows for a clean way to pass arguments, - # with each parent "peeling a layer of the onion". + # The use of *args and **kwargs allows for a clean way to pass + # arguments, with each parent "peeling a layer of the onion". Superhero.__init__(self, 'anonymous', movie=True, superpowers=['Wealthy'], *args, **kwargs) Bat.__init__(self, *args, can_fly=False, **kwargs) @@ -1039,8 +1041,6 @@ print(say()) # Can you buy me a beer? print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :( ``` -## Ready For More? - ### Free Online * [Automate the Boring Stuff with Python](https://automatetheboringstuff.com) -- cgit v1.2.3 From 968661d9f76bdeeaf0b1fcbf905de15991214778 Mon Sep 17 00:00:00 2001 From: ShenMian <70068015+ShenMian@users.noreply.github.com> Date: Thu, 10 Nov 2022 11:37:19 +0800 Subject: Update vim.html.markdown --- vim.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vim.html.markdown b/vim.html.markdown index f5be9b0d..e0fdf2e0 100644 --- a/vim.html.markdown +++ b/vim.html.markdown @@ -29,7 +29,7 @@ specific points in the file, and for fast editing. :q! # Quit vim without saving file # ! *forces* :q to execute, hence quiting vim without saving ZQ # Quit vim without saving file - :x # Save file and quit vim, shorter version of :wq + :x # Save file(only when the file is modified) and quit vim u # Undo CTRL+R # Redo -- cgit v1.2.3 From 873314f253a37932f836354b482fcda03f0bf505 Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Fri, 11 Nov 2022 10:38:32 +0100 Subject: add link to markdownlint It already was mentioned, the additional link eases installation and thus promotes its subsequent use. --- markdown.html.markdown | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/markdown.html.markdown b/markdown.html.markdown index a6000910..cfc0ddf3 100644 --- a/markdown.html.markdown +++ b/markdown.html.markdown @@ -40,9 +40,9 @@ specific to a certain parser. Markdown is a superset of HTML, so any HTML file is valid Markdown. ```md - ``` @@ -370,9 +370,10 @@ Ugh this is so ugly | make it | stop ## Markdownlint In order to simplify work with Markdown and to unify its coding style, -`Markdownlint` has been created. This tool is available also as a plugin for -some IDEs and can be used as an utility to ensure validity and readability of -Markdown. +`Markdownlint` has been created. Available as a +[separate tool](https://github.com/markdownlint/markdownlint) +as well as a plugin for some IDEs, it can be used to ensure validity and +readability of Markdown. --- -- cgit v1.2.3 From ab877e93eb7dfc8536683d5862477fb62f3b224b Mon Sep 17 00:00:00 2001 From: Yann Defretin Date: Fri, 11 Nov 2022 17:49:24 +0100 Subject: [javascript/fr] Fix equality comparison example (#4540) --- fr-fr/javascript-fr.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fr-fr/javascript-fr.html.markdown b/fr-fr/javascript-fr.html.markdown index 186859ab..308f1ca8 100644 --- a/fr-fr/javascript-fr.html.markdown +++ b/fr-fr/javascript-fr.html.markdown @@ -94,7 +94,7 @@ let banta = "Harry", santa = "Hermione"; // L'égalité est === ou == // === compare la valeur exacte 2 === '2' // = false -// == convertit la valeur pour comparer 2 === '2' // = true +// == convertit la valeur pour comparer 2 == '2' // = true // En général, il vaut mieux utiliser === pour ne pas faire d'erreur. 1 === 1; // = true 2 === 1; // = false -- cgit v1.2.3 From 5a9b474a635a1b0b12908f8673b6f4e1e67d0812 Mon Sep 17 00:00:00 2001 From: Akshita Dixit <436_bt19@iiitkalyani.ac.in> Date: Sun, 13 Nov 2022 14:24:24 +0530 Subject: [Docs]: Docker documentation revamp --- docker.html.markdown | 259 ++++++++++++++++++++++++--------------------------- 1 file changed, 120 insertions(+), 139 deletions(-) diff --git a/docker.html.markdown b/docker.html.markdown index 1df49cc3..d65947fe 100644 --- a/docker.html.markdown +++ b/docker.html.markdown @@ -5,144 +5,125 @@ filename: docker.bat contributors: - ["Ruslan López", "http://javapro.org/"] - ["Michael Chen", "https://github.com/ML-Chen"] + - ["Akshita Dixit", "https://github.com/akshitadixit"] --- -```bat -:: download, install and run hello-world image -docker run hello-world - -:: if this is the first time you should be able to see the message -:: Unable to find image 'hello-world:latest' locally -:: latest: Pulling from library/hello-world -:: 1b930d010525: Pull complete -:: Digest: sha256:4fe721ccc2e8dc7362278a29dc660d833570ec2682f4e4194f4ee23e415e1064 -:: Status: Downloaded newer image for hello-world:latest -:: -:: Hello from Docker! -:: This message shows that your installation appears to be working correctly. -:: -:: To generate this message, Docker took the following steps: -:: 1. The Docker client contacted the Docker daemon. -:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. -:: (amd64) -:: 3. The Docker daemon created a new container from that image which runs the -:: executable that produces the output you are currently reading. -:: 4. The Docker daemon streamed that output to the Docker client, which sent it -:: to your terminal. -:: -:: To try something more ambitious, you can run an Ubuntu container with: -:: $ docker run -it ubuntu bash -:: -:: Share images, automate workflows, and more with a free Docker ID: -:: https://hub.docker.com/ -:: -:: For more examples and ideas, visit: -:: https://docs.docker.com/get-started/ - -:: now let's see currently running images -docker ps -:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS -:: NAMES - -:: let's see the images we have ran previously -docker ps -a - -:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS -:: NAMES -:: 4a76281f9c53 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago -:: happy_poincare -:: the name part is generated automatically so it probably will be different for you - -:: let's remove our previously generated image -docker rm happy_poincare - -:: let's test if it was really deleted -docker ps -a -:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS -:: NAMES - -:: specify a custom name for the container -docker run --name test_container hello-world -:: Hello from Docker! -:: This message shows that your installation appears to be working correctly. -:: -:: To generate this message, Docker took the following steps: -:: 1. The Docker client contacted the Docker daemon. -:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. -:: (amd64) -:: 3. The Docker daemon created a new container from that image which runs the -:: executable that produces the output you are currently reading. -:: 4. The Docker daemon streamed that output to the Docker client, which sent it -:: to your terminal. -:: -:: To try something more ambitious, you can run an Ubuntu container with: -:: $ docker run -it ubuntu bash -:: -:: Share images, automate workflows, and more with a free Docker ID: -:: https://hub.docker.com/ -:: -:: For more examples and ideas, visit: -:: https://docs.docker.com/get-started/ - -docker ps -a -:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS -:: NAMES -:: d345fe1a4f41 hello-world "/hello" About a minute ago Exited (0) About a minute ago -:: test_container -:: as you can see the name is now what we have specified - -:: retrieve logs from a named container -docker logs test_container -:: Hello from Docker! -:: This message shows that your installation appears to be working correctly. -:: -:: To generate this message, Docker took the following steps: -:: 1. The Docker client contacted the Docker daemon. -:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. -:: (amd64) -:: 3. The Docker daemon created a new container from that image which runs the -:: executable that produces the output you are currently reading. -:: 4. The Docker daemon streamed that output to the Docker client, which sent it -:: to your terminal. -:: -:: To try something more ambitious, you can run an Ubuntu container with: -:: $ docker run -it ubuntu bash -:: -:: Share images, automate workflows, and more with a free Docker ID: -:: https://hub.docker.com/ -:: -:: For more examples and ideas, visit: -:: https://docs.docker.com/get-started/ - -docker rm test_container - -docker run ubuntu -:: Unable to find image 'ubuntu:latest' locally -:: latest: Pulling from library/ubuntu -:: 2746a4a261c9: Pull complete -:: 4c1d20cdee96: Pull complete 0d3160e1d0de: Pull complete c8e37668deea: Pull complete Digest: sha256:250cc6f3f3ffc5cdaa9d8f4946ac79821aafb4d3afc93928f0de9336eba21aa4 -:: Status: Downloaded newer image for ubuntu:latest - -docker ps -a -:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS -:: NAMES -:: c19e9e5b000a ubuntu "/bin/bash" 5 seconds ago Exited (0) 4 seconds ago -:: relaxed_nobel - -:: running a container in an interactive mode -docker run -it ubuntu -:: root@e2cac48323d2:/# uname -:: Linux -:: root@e2cac48323d2:/# exit -:: exit - -docker rm relaxed_nobel - -docker ps -a -:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS -:: NAMES -:: e2cac48323d2 ubuntu "/bin/bash" 2 minutes ago Exited (0) About a minute ago -:: nifty_goldwasser - -docker rm nifty_goldwasser -``` +Docker is a tool that helps you build, test, ship and run applications seamlessly across various machines. It replicates the environment our software needs on any machine. You can get Docker for your machine from https://docs.docker.com/get-docker/ + +It has grown in popularity over the last decade due to being lightweight and fast as compared to virtual-machines that are bulky and slow. Unlike VMs, docker does not need a full blown OS of its own to be loaded to start and does not compete for resources other than what the application it is running will use. VMs on the other hand are pretty resource intensive on our processors, disks and memory hence running multiple VMs for various applications becomes a challenge in a limited capacity architecture. +
+┌────────────────────────┐ ┌───────────────────────┐                ┌────────────────────────┐ ┌───────────────────────┐
+│      ┌───────────┐     │ │      ┌───────────┐    │                │      ┌───────────┐     │ │      ┌───────────┐    │
+│      │   App     │     │ │      │   App     │    │                │      │   App     │     │ │      │   App     │    │
+│      └───────────┘     │ │      └───────────┘    │                │      └───────────┘     │ │      └───────────┘    │
+│  ┌────────┐ ┌────────┐ │ │  ┌────────┐ ┌───────┐ │                │  ┌────────┐ ┌────────┐ │ │  ┌────────┐ ┌───────┐ │
+│  │  Libs  │ │  Deps  │ │ │  │  Libs  │ │  Deps │ │                │  │  Libs  │ │  Deps  │ │ │  │  Libs  │ │  Deps │ │
+│  └────────┘ └────────┘ │ │  └────────┘ └───────┘ │                │  └────────┘ └────────┘ │ │  └────────┘ └───────┘ │
+│  ┌───────────────────┐ │ │  ┌──────────────────┐ │                │        Container1      │ │       Container2      │
+│  │         OS        │ │ │  │         OS       │ │                └────────────────────────┘ └───────────────────────┘
+│  └───────────────────┘ │ │  └──────────────────┘ │                ┌──────────────────────────────────────────────────┐
+│           VM1          │ │           VM2         │                │                       Docker                     │
+└────────────────────────┘ └───────────────────────┘                └──────────────────────────────────────────────────┘
+┌──────────────────────────────────────────────────┐                ┌──────────────────────────────────────────────────┐
+│                     Hypervisor                   │                │                        OS                        │
+└──────────────────────────────────────────────────┘                └──────────────────────────────────────────────────┘
+┌───────────────────────────────────────────────────┐               ┌──────────────────────────────────────────────────┐
+│             Hardware Infrastructure               │               │             Hardware Infrastructure              │
+└───────────────────────────────────────────────────┘               └──────────────────────────────────────────────────┘
+            (VM based architecture)                                                 (Docker based architecture)
+
+ +Couple of terms we will encounter frequently are Docker Images and Docker Containers. Images are packages or templates of containers all stored in the [Docker Hub](https://hub.docker.com/). Containers are standalone, executable instances of these images which include code, runtime, system tools, system libraries and settings - everything required to get the software up and running. Coming to Docker, it follows a client-server architecture wherein the CLI client communicates with the server component, which here is, the Docker Engine using RESTful API to issue commands. + +## The Docker CLI +```bash +# after installing Docker from https://docs.docker.com/get-docker/ +# To list available commands, either run `docker` with no parameters or execute `docker help` +$docker + +>>> docker [OPTIONS] COMMAND [ARG...] + docker [ --help | -v | --version ] + + A self-sufficient runtime for containers. + + Options: + --config string Location of client config files (default "/root/.docker") + -c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use") + -D, --debug Enable debug mode + --help Print usage + -H, --host value Daemon socket(s) to connect to (default []) + -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") + --tls Use TLS; implied by --tlsverify + --tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem") + --tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem") + --tlskey string Path to TLS key file (default "/root/.docker/key.pem") + --tlsverify Use TLS and verify the remote + -v, --version Print version information and quit + + Commands: + attach Attach to a running container + # […] + +$docker run hello-world +# `docker run ` is used to run a container, it will pull the images from Docker Hub if they don't alrady exist on your system +# Here the docker client connects to the daemon which in turn pulls the "hello-world" image from the Docker Hub. The daemon then creates a +# new container from the image which runs the executable that produces the output streamed back to the client that we see on our terminals. + +$docker run -d ubuntu sleep 60s +# The -d (or --detach) flag is when we want to run a container in the background and return back to the terminal. +# Here we detach an ubuntu container from the terminal, the output should be the id and the command exits. If we check running containers, +# we should still see ours there: +# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +# 133261b4894a ubuntu "sleep 60s" 3 seconds ago Up 2 seconds vigorous_gould + +$docker run -p 3000:8000 +# The -p (or --publish) flag is used to expose port 8000 inside the container to port 3000 outside the container +# This is because the app inside the container runs in isolation, hence the port 8000 where the app runs is private to the container. + +$docker run -i or $docker run -it +# Docker runs our containers in a non-interactive mode i.e. they do not accept inputs or work dynamically while running. +# The -i flag keeps input open to the container, and the -t flag creates a pseudo-terminal that the shell can attach to (can be combined as -it) + +$docker ps -a +# The `docker ps` command only shows running containers by default. To see all containers, use the -a (or --all) flag +# Running the above command should output something similar in the terminal: +# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +# 82f84bf6912b hello-world "/hello" 9 minutes ago Exited (0) 9 minutes ago eloquent_sammet + + +$docker start hello-world or $docker stop hello-world +# The stop command simply stops one or more containers, the start command starts the conatainer(s) up again! +# `docker start -a ubuntu` will attach our detached container back to the terminal i.e. runs in the foreground + +$docker create alpine +# `docker create` creates a new container for us with the image specified (here, alpine), the container does not auto-start unlike `docker run` +# This command is used to set up a container configuration and then `docker start` to shoot it up when required. Note that the status is "Created": +# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +# 4c71c727c73d alpine "/bin/sh" 29 seconds ago Created naughty_ritchie + +$docker rm 82f84 +# Removes one or more containers using their container ID. +# P.S.: we can use only the first few characters of the entire ID to identify containers + +$docker images +# Displays all images and their information, created here means the latest image tag updated on Docker Hub: +# REPOSITORY TAG IMAGE ID CREATED SIZE +# ubuntu latest a8780b506fa4 9 days ago 77.8MB +# alpine latest 9c6f07244728 3 months ago 5.54MB +# hello-world latest feb5d9fea6a5 13 months ago 13.3kB + +$docker rmi +# Removes one or more images from your system which do not have their instances (or containers as we know them) running. +# If the image has an attached container, either delete the container first or use the -f (or --force) flag to forcefully delete both the container and image. + +$docker pull busybox +# The pull command downloads the specified image on our system from Docker Hub. + +$docker exec -it 7b272 bash +# This command is used to run a command in the running container's default directory +# Here 7b272 was our ubuntu container and the above command would help us interact with the container by opening a bash session + +$docker compose + +# More commands can be found at https://docs.docker.com/engine/reference/commandline/docker/ +``` \ No newline at end of file -- cgit v1.2.3 From 7b10b3e9a6f177ccaa99b926fe15bd821a94e18e Mon Sep 17 00:00:00 2001 From: Marcel Ribeiro Dantas Date: Sun, 13 Nov 2022 12:45:49 -0300 Subject: Keep lines under 80 chars whenever possible --- docker.html.markdown | 147 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 102 insertions(+), 45 deletions(-) diff --git a/docker.html.markdown b/docker.html.markdown index d65947fe..d64c9b1c 100644 --- a/docker.html.markdown +++ b/docker.html.markdown @@ -6,39 +6,79 @@ contributors: - ["Ruslan López", "http://javapro.org/"] - ["Michael Chen", "https://github.com/ML-Chen"] - ["Akshita Dixit", "https://github.com/akshitadixit"] + - ["Marcel Ribeiro-Dantas", "https://github.com/mribeirodantas"] --- -Docker is a tool that helps you build, test, ship and run applications seamlessly across various machines. It replicates the environment our software needs on any machine. You can get Docker for your machine from https://docs.docker.com/get-docker/ +Docker is a tool that helps you build, test, ship and run applications +seamlessly across various machines. It replicates the environment our software +needs on any machine. You can get Docker for your machine from +https://docs.docker.com/get-docker/ + +It has grown in popularity over the last decade due to being lightweight and +fast as compared to virtual-machines that are bulky and slow. Unlike VMs, docker +does not need a full blown OS of its own to be loaded to start and does not +compete for resources other than what the application it is running will use. +VMs on the other hand are pretty resource intensive on our processors, disks and +memory hence running multiple VMs for various applications becomes a challenge +in a limited capacity architecture. -It has grown in popularity over the last decade due to being lightweight and fast as compared to virtual-machines that are bulky and slow. Unlike VMs, docker does not need a full blown OS of its own to be loaded to start and does not compete for resources other than what the application it is running will use. VMs on the other hand are pretty resource intensive on our processors, disks and memory hence running multiple VMs for various applications becomes a challenge in a limited capacity architecture.
-┌────────────────────────┐ ┌───────────────────────┐                ┌────────────────────────┐ ┌───────────────────────┐
-│      ┌───────────┐     │ │      ┌───────────┐    │                │      ┌───────────┐     │ │      ┌───────────┐    │
-│      │   App     │     │ │      │   App     │    │                │      │   App     │     │ │      │   App     │    │
-│      └───────────┘     │ │      └───────────┘    │                │      └───────────┘     │ │      └───────────┘    │
-│  ┌────────┐ ┌────────┐ │ │  ┌────────┐ ┌───────┐ │                │  ┌────────┐ ┌────────┐ │ │  ┌────────┐ ┌───────┐ │
-│  │  Libs  │ │  Deps  │ │ │  │  Libs  │ │  Deps │ │                │  │  Libs  │ │  Deps  │ │ │  │  Libs  │ │  Deps │ │
-│  └────────┘ └────────┘ │ │  └────────┘ └───────┘ │                │  └────────┘ └────────┘ │ │  └────────┘ └───────┘ │
-│  ┌───────────────────┐ │ │  ┌──────────────────┐ │                │        Container1      │ │       Container2      │
-│  │         OS        │ │ │  │         OS       │ │                └────────────────────────┘ └───────────────────────┘
-│  └───────────────────┘ │ │  └──────────────────┘ │                ┌──────────────────────────────────────────────────┐
-│           VM1          │ │           VM2         │                │                       Docker                     │
-└────────────────────────┘ └───────────────────────┘                └──────────────────────────────────────────────────┘
-┌──────────────────────────────────────────────────┐                ┌──────────────────────────────────────────────────┐
-│                     Hypervisor                   │                │                        OS                        │
-└──────────────────────────────────────────────────┘                └──────────────────────────────────────────────────┘
-┌───────────────────────────────────────────────────┐               ┌──────────────────────────────────────────────────┐
-│             Hardware Infrastructure               │               │             Hardware Infrastructure              │
-└───────────────────────────────────────────────────┘               └──────────────────────────────────────────────────┘
-            (VM based architecture)                                                 (Docker based architecture)
+┌────────────────────────┐ ┌───────────────────────┐
+│      ┌───────────┐     │ │      ┌───────────┐    │
+│      │   App     │     │ │      │   App     │    │
+│      └───────────┘     │ │      └───────────┘    │
+│  ┌────────┐ ┌────────┐ │ │  ┌────────┐ ┌───────┐ │
+│  │  Libs  │ │  Deps  │ │ │  │  Libs  │ │  Deps │ │
+│  └────────┘ └────────┘ │ │  └────────┘ └───────┘ │
+│  ┌───────────────────┐ │ │  ┌──────────────────┐ │
+│  │         OS        │ │ │  │         OS       │ │
+│  └───────────────────┘ │ │  └──────────────────┘ │
+│           VM1          │ │           VM2         │
+└────────────────────────┘ └───────────────────────┘
+┌──────────────────────────────────────────────────┐
+│                     Hypervisor                   │
+└──────────────────────────────────────────────────┘
+┌──────────────────────────────────────────────────┐
+│             Hardware Infrastructure              │
+└──────────────────────────────────────────────────┘
+              (VM based architecture)
+
+┌────────────────────────┐ ┌───────────────────────┐
+│      ┌───────────┐     │ │      ┌───────────┐    │
+│      │   App     │     │ │      │   App     │    │
+│      └───────────┘     │ │      └───────────┘    │
+│  ┌────────┐ ┌────────┐ │ │  ┌────────┐ ┌───────┐ │
+│  │  Libs  │ │  Deps  │ │ │  │  Libs  │ │  Deps │ │
+│  └────────┘ └────────┘ │ │  └────────┘ └───────┘ │
+│        Container1      │ │       Container2      │
+└────────────────────────┘ └───────────────────────┘
+┌──────────────────────────────────────────────────┐
+│                       Docker                     │
+└──────────────────────────────────────────────────┘
+┌──────────────────────────────────────────────────┐
+│                        OS                        │
+└──────────────────────────────────────────────────┘
+┌──────────────────────────────────────────────────┐
+│             Hardware Infrastructure              │
+└──────────────────────────────────────────────────┘
+            (Docker based architecture)
+
 
-Couple of terms we will encounter frequently are Docker Images and Docker Containers. Images are packages or templates of containers all stored in the [Docker Hub](https://hub.docker.com/). Containers are standalone, executable instances of these images which include code, runtime, system tools, system libraries and settings - everything required to get the software up and running. Coming to Docker, it follows a client-server architecture wherein the CLI client communicates with the server component, which here is, the Docker Engine using RESTful API to issue commands. +Couple of terms we will encounter frequently are Docker Images and Docker +Containers. Images are packages or templates of containers all stored in the +[Docker Hub](https://hub.docker.com/). Containers are standalone, executable +instances of these images which include code, runtime, system tools, system +libraries and settings - everything required to get the software up and running. +Coming to Docker, it follows a client-server architecture wherein the CLI client +communicates with the server component, which here is, the Docker Engine using +RESTful API to issue commands. ## The Docker CLI ```bash # after installing Docker from https://docs.docker.com/get-docker/ -# To list available commands, either run `docker` with no parameters or execute `docker help` +# To list available commands, either run `docker` with no parameters or execute +# `docker help` $docker >>> docker [OPTIONS] COMMAND [ARG...] @@ -65,65 +105,82 @@ $docker # […] $docker run hello-world -# `docker run ` is used to run a container, it will pull the images from Docker Hub if they don't alrady exist on your system -# Here the docker client connects to the daemon which in turn pulls the "hello-world" image from the Docker Hub. The daemon then creates a -# new container from the image which runs the executable that produces the output streamed back to the client that we see on our terminals. +# `docker run ` is used to run a container, it will pull the +# images from Docker Hub if they don't alrady exist on your system. Here the +# docker client connects to the daemon which in turn pulls the "hello-world" +# image from the Docker Hub. The daemon then creates a new container from the +# image which runs the executable that produces the output streamed back to the +# client that we see on our terminals. $docker run -d ubuntu sleep 60s -# The -d (or --detach) flag is when we want to run a container in the background and return back to the terminal. -# Here we detach an ubuntu container from the terminal, the output should be the id and the command exits. If we check running containers, -# we should still see ours there: +# The -d (or --detach) flag is when we want to run a container in the background +# and return back to the terminal. Here we detach an ubuntu container from the +# terminal, the output should be the id and the command exits. If we check +# running containers, we should still see ours there: # CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES # 133261b4894a ubuntu "sleep 60s" 3 seconds ago Up 2 seconds vigorous_gould $docker run -p 3000:8000 -# The -p (or --publish) flag is used to expose port 8000 inside the container to port 3000 outside the container -# This is because the app inside the container runs in isolation, hence the port 8000 where the app runs is private to the container. +# The -p (or --publish) flag is used to expose port 8000 inside the container to +# port 3000 outside the container. This is because the app inside the container +# runs in isolation, hence the port 8000 where the app runs is private to the +# container. $docker run -i or $docker run -it -# Docker runs our containers in a non-interactive mode i.e. they do not accept inputs or work dynamically while running. -# The -i flag keeps input open to the container, and the -t flag creates a pseudo-terminal that the shell can attach to (can be combined as -it) +# Docker runs our containers in a non-interactive mode i.e. they do not accept +# inputs or work dynamically while running. The -i flag keeps input open to the +# container, and the -t flag creates a pseudo-terminal that the shell can attach +# to (can be combined as -it) $docker ps -a -# The `docker ps` command only shows running containers by default. To see all containers, use the -a (or --all) flag +# The `docker ps` command only shows running containers by default. To see all +# containers, use the -a (or --all) flag # Running the above command should output something similar in the terminal: # CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES # 82f84bf6912b hello-world "/hello" 9 minutes ago Exited (0) 9 minutes ago eloquent_sammet $docker start hello-world or $docker stop hello-world -# The stop command simply stops one or more containers, the start command starts the conatainer(s) up again! -# `docker start -a ubuntu` will attach our detached container back to the terminal i.e. runs in the foreground +# The stop command simply stops one or more containers, the start command starts +# the conatainer(s) up again! `docker start -a ubuntu` will attach our detached +# container back to the terminal i.e. runs in the foreground $docker create alpine -# `docker create` creates a new container for us with the image specified (here, alpine), the container does not auto-start unlike `docker run` -# This command is used to set up a container configuration and then `docker start` to shoot it up when required. Note that the status is "Created": +# `docker create` creates a new container for us with the image specified (here, +# alpine), the container does not auto-start unlike `docker run`. This command +# is used to set up a container configuration and then `docker start` to shoot +# it up when required. Note that the status is "Created": # CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES # 4c71c727c73d alpine "/bin/sh" 29 seconds ago Created naughty_ritchie $docker rm 82f84 # Removes one or more containers using their container ID. -# P.S.: we can use only the first few characters of the entire ID to identify containers +# P.S.: we can use only the first few characters of the entire ID to identify +# containers $docker images -# Displays all images and their information, created here means the latest image tag updated on Docker Hub: +# Displays all images and their information, created here means the latest image +# tag updated on Docker Hub: # REPOSITORY TAG IMAGE ID CREATED SIZE # ubuntu latest a8780b506fa4 9 days ago 77.8MB # alpine latest 9c6f07244728 3 months ago 5.54MB # hello-world latest feb5d9fea6a5 13 months ago 13.3kB $docker rmi -# Removes one or more images from your system which do not have their instances (or containers as we know them) running. -# If the image has an attached container, either delete the container first or use the -f (or --force) flag to forcefully delete both the container and image. +# Removes one or more images from your system which do not have their instances +# (or containers as we know them) running. If the image has an attached +# container, either delete the container first or use the -f (or --force) flag +# to forcefully delete both the container and image. $docker pull busybox # The pull command downloads the specified image on our system from Docker Hub. $docker exec -it 7b272 bash -# This command is used to run a command in the running container's default directory -# Here 7b272 was our ubuntu container and the above command would help us interact with the container by opening a bash session +# This command is used to run a command in the running container's default +# directory. Here 7b272 was our ubuntu container and the above command would +# help us interact with the container by opening a bash session $docker compose # More commands can be found at https://docs.docker.com/engine/reference/commandline/docker/ -``` \ No newline at end of file +``` -- cgit v1.2.3 From f0577fb679c63be3c47d7429361002dd1331aff5 Mon Sep 17 00:00:00 2001 From: Marcel Ribeiro Dantas Date: Sun, 13 Nov 2022 12:47:37 -0300 Subject: Add host/guest OS info on VM-based architecture diagram --- docker.html.markdown | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docker.html.markdown b/docker.html.markdown index d64c9b1c..ca81cc45 100644 --- a/docker.html.markdown +++ b/docker.html.markdown @@ -31,7 +31,7 @@ in a limited capacity architecture. │ │ Libs │ │ Deps │ │ │ │ Libs │ │ Deps │ │ │ └────────┘ └────────┘ │ │ └────────┘ └───────┘ │ │ ┌───────────────────┐ │ │ ┌──────────────────┐ │ -│ │ OS │ │ │ │ OS │ │ +│ │ Guest OS │ │ │ │ Guest OS │ │ │ └───────────────────┘ │ │ └──────────────────┘ │ │ VM1 │ │ VM2 │ └────────────────────────┘ └───────────────────────┘ @@ -39,6 +39,9 @@ in a limited capacity architecture. │ Hypervisor │ └──────────────────────────────────────────────────┘ ┌──────────────────────────────────────────────────┐ +│ Host OS │ +└──────────────────────────────────────────────────┘ +┌──────────────────────────────────────────────────┐ │ Hardware Infrastructure │ └──────────────────────────────────────────────────┘ (VM based architecture) -- cgit v1.2.3 From 5630c3e05ac3d445b663ca1d1188d0b93b21fb35 Mon Sep 17 00:00:00 2001 From: Marcel Ribeiro Dantas Date: Sun, 13 Nov 2022 12:59:50 -0300 Subject: Improve wording/typos --- docker.html.markdown | 58 ++++++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/docker.html.markdown b/docker.html.markdown index ca81cc45..f69dbddb 100644 --- a/docker.html.markdown +++ b/docker.html.markdown @@ -69,20 +69,20 @@ in a limited capacity architecture. Couple of terms we will encounter frequently are Docker Images and Docker -Containers. Images are packages or templates of containers all stored in the -[Docker Hub](https://hub.docker.com/). Containers are standalone, executable -instances of these images which include code, runtime, system tools, system -libraries and settings - everything required to get the software up and running. -Coming to Docker, it follows a client-server architecture wherein the CLI client -communicates with the server component, which here is, the Docker Engine using -RESTful API to issue commands. +Containers. Images are packages or templates of containers all stored in a +container registry such as [Docker Hub](https://hub.docker.com/). Containers +are standalone, executable instances of these images which include code, +runtime, system tools, system libraries and settings - everything required to +get the software up and running. Coming to Docker, it follows a client-server +architecture wherein the CLI client communicates with the server component, +which here is, the Docker Engine using RESTful API to issue commands. ## The Docker CLI ```bash # after installing Docker from https://docs.docker.com/get-docker/ # To list available commands, either run `docker` with no parameters or execute # `docker help` -$docker +$ docker >>> docker [OPTIONS] COMMAND [ARG...] docker [ --help | -v | --version ] @@ -107,15 +107,15 @@ $docker attach Attach to a running container # […] -$docker run hello-world +$ docker run hello-world # `docker run ` is used to run a container, it will pull the -# images from Docker Hub if they don't alrady exist on your system. Here the +# images from Docker Hub if they don't already exist in your system. Here the # docker client connects to the daemon which in turn pulls the "hello-world" -# image from the Docker Hub. The daemon then creates a new container from the +# image from the Docker Hub. The daemon then builds a new container from the # image which runs the executable that produces the output streamed back to the # client that we see on our terminals. -$docker run -d ubuntu sleep 60s +$ docker run -d ubuntu sleep 60s # The -d (or --detach) flag is when we want to run a container in the background # and return back to the terminal. Here we detach an ubuntu container from the # terminal, the output should be the id and the command exits. If we check @@ -123,19 +123,21 @@ $docker run -d ubuntu sleep 60s # CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES # 133261b4894a ubuntu "sleep 60s" 3 seconds ago Up 2 seconds vigorous_gould -$docker run -p 3000:8000 +$ docker run -p 3000:8000 # The -p (or --publish) flag is used to expose port 8000 inside the container to # port 3000 outside the container. This is because the app inside the container # runs in isolation, hence the port 8000 where the app runs is private to the # container. -$docker run -i or $docker run -it +$ docker run -i +# or +$ docker run -it # Docker runs our containers in a non-interactive mode i.e. they do not accept # inputs or work dynamically while running. The -i flag keeps input open to the # container, and the -t flag creates a pseudo-terminal that the shell can attach # to (can be combined as -it) -$docker ps -a +$ docker ps -a # The `docker ps` command only shows running containers by default. To see all # containers, use the -a (or --all) flag # Running the above command should output something similar in the terminal: @@ -143,12 +145,14 @@ $docker ps -a # 82f84bf6912b hello-world "/hello" 9 minutes ago Exited (0) 9 minutes ago eloquent_sammet -$docker start hello-world or $docker stop hello-world -# The stop command simply stops one or more containers, the start command starts -# the conatainer(s) up again! `docker start -a ubuntu` will attach our detached -# container back to the terminal i.e. runs in the foreground +$ docker stop hello-world +# or +$ docker start hello-world +# The stop command simply stops one or more containers, and the start command +# starts the container(s) up again! `docker start -a ubuntu` will attach our +# detached container back to the terminal i.e. runs in the foreground -$docker create alpine +$ docker create alpine # `docker create` creates a new container for us with the image specified (here, # alpine), the container does not auto-start unlike `docker run`. This command # is used to set up a container configuration and then `docker start` to shoot @@ -156,12 +160,12 @@ $docker create alpine # CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES # 4c71c727c73d alpine "/bin/sh" 29 seconds ago Created naughty_ritchie -$docker rm 82f84 +$ docker rm 82f84 # Removes one or more containers using their container ID. # P.S.: we can use only the first few characters of the entire ID to identify # containers -$docker images +$ docker images # Displays all images and their information, created here means the latest image # tag updated on Docker Hub: # REPOSITORY TAG IMAGE ID CREATED SIZE @@ -169,21 +173,21 @@ $docker images # alpine latest 9c6f07244728 3 months ago 5.54MB # hello-world latest feb5d9fea6a5 13 months ago 13.3kB -$docker rmi +$ docker rmi # Removes one or more images from your system which do not have their instances # (or containers as we know them) running. If the image has an attached # container, either delete the container first or use the -f (or --force) flag # to forcefully delete both the container and image. -$docker pull busybox +$ docker pull busybox # The pull command downloads the specified image on our system from Docker Hub. -$docker exec -it 7b272 bash +$ docker exec -it 7b272 bash # This command is used to run a command in the running container's default # directory. Here 7b272 was our ubuntu container and the above command would -# help us interact with the container by opening a bash session +# help us interact with the container by opening a bash session. -$docker compose +$ docker compose # More commands can be found at https://docs.docker.com/engine/reference/commandline/docker/ ``` -- cgit v1.2.3 From 75b0cfb4ab74aa11adee90a820366c18be6b185b Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Mon, 14 Nov 2022 12:14:46 +0100 Subject: trim trailing spaces An instance of `sed -i 's/ *$//' vim-de.html.markdown`. --- de-de/vim-de.html.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/de-de/vim-de.html.markdown b/de-de/vim-de.html.markdown index 93fd9773..40e5afe5 100644 --- a/de-de/vim-de.html.markdown +++ b/de-de/vim-de.html.markdown @@ -12,7 +12,7 @@ filename: LearnVim-de.txt [Vim](http://www.vim.org) (Vi IMproved) ist ein Klon von vi, dem bekannten Editor für Unix. Es ist ein -Texteditor, welcher mit Fokus auf Geschwindigkeit und Prouktivität entwickelt +Texteditor, welcher mit Fokus auf Geschwindigkeit und Prouktivität entwickelt wurde. Vim hat viele Keybindings für ein schnelles navigieren und schnelles bearbeiten einer Datei. @@ -168,7 +168,7 @@ Einige wichtige Beispiele von 'Verb', 'Modifier' und 'Nouns': d2w # lösche zwei Wörter cis # Ändere innerhalb des Satzes. - yip # Kopiere innerhalb des Abschnitts (kopiere den Abschnitt, + yip # Kopiere innerhalb des Abschnitts (kopiere den Abschnitt, # in welchem du bist) ct< # Ändere bis zur spitzen Klammer # Ändere den Text von deiner aktuellen Cursorposition bis @@ -181,7 +181,7 @@ Einige wichtige Beispiele von 'Verb', 'Modifier' und 'Nouns': ``` > # Rücke die Auswahl um einen Block ein < # Lösche eine Einrückung der Auswahl - :earlier 15m # Stellt das Dokument so wieder her, wie es vor 15 + :earlier 15m # Stellt das Dokument so wieder her, wie es vor 15 # Minuten war :later 15m # den oberen Befehl rückgängig machen ddp # Vertauschen zweier aufeinanderfolgenden Zeilen @@ -195,7 +195,7 @@ Einige wichtige Beispiele von 'Verb', 'Modifier' und 'Nouns': ~ # Umschalten der Groß-/Kleinschreibung des ausgewählten Textes u # Ausgewählten Text zu Kleinschreibung ändern U # Ausgewählten Text zu Großschreibung ändern - + # Text-Folding (Textfaltung) zf # Erstelle eine Faltung des ausgewählten Textes zo # Öffne die aktuelle Faltung -- cgit v1.2.3 From 8dd734971d05c1a7d9b0709df546ce8ae11fc34b Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Mon, 14 Nov 2022 12:15:37 +0100 Subject: trim leading spaces (needs manual correction) An instance of `sed -i 's/^ *//' vim-de.html.markdown`. --- de-de/vim-de.html.markdown | 292 ++++++++++++++++++++++----------------------- 1 file changed, 146 insertions(+), 146 deletions(-) diff --git a/de-de/vim-de.html.markdown b/de-de/vim-de.html.markdown index 40e5afe5..707bae5b 100644 --- a/de-de/vim-de.html.markdown +++ b/de-de/vim-de.html.markdown @@ -3,9 +3,9 @@ category: tool tool: vim lang: de-de contributors: - - ["RadhikaG", "https://github.com/RadhikaG"] +- ["RadhikaG", "https://github.com/RadhikaG"] translators: - - ["caminsha", "https://github.com/caminsha"] +- ["caminsha", "https://github.com/caminsha"] filename: LearnVim-de.txt --- @@ -20,74 +20,74 @@ einer Datei. ## Grundlagen, um in Vim zu navigieren ``` - vim # Öffne in Vim - :help # Öffne die eingebaute Hilfe zum Thema , wenn - # es existiert - :q # Schließe vim - :w # Speichere diese Datei - :wq # Speichere diese Datei und schließe vim - ZZ # Speichere diese Datei und schließe vim - :q! # Schließe vim ohne die Datei zu speichern - # ! *zwingt* die Ausführung von :q, - # daher wird die Datei nicht gespeichert. - ZQ # Beende vim ohne die Datei zu speichern - :x # Speichere die Datei und beende vim - # Dies ist eine kürzere Version von :wq - - u # Änderung rückgängig machen - CTRL+R # Änderung wiederherstellen - - h # Den Cursor um ein Zeichen nach links bewegen - j # Den Cursor eine Zeile nach unten bewegen - k # Den Cursor eine Zeile nach oben bewegen - l # Den Cursor um ein Zeichen nach rechts bewegen - - Ctrl+B # Gehe eine Bildschirmanzeige zurück - Ctrl+F # Gehe eine Bildschirmanzeige vorwärts - Ctrl+D # Gehe eine halbe Bildschirmanzeige vorwärts - Ctrl+U # Gehe eine halbe Bildschirmanzeige zurück - - # Navigieren innerhalb einer Zeile - - 0 # Navigiere zum Anfang der Zeile - $ # Navigiere zum Ende der Zeile - ^ # Navigiere zum ersten Zeichen, welches kein Leerzeichen ist - - # Im Text suchen - - /word # Hebt alle Ergebnisse nach dem Cursor hervor - ?word # Hebt alle Ergebnisse vor dem Cursor hervor - n # Bewegt den Cursor zum nächsten Ergebnis nach der Suche - N # Bewegt den Cursor zum vorherigen Ergebnis der Suche - - :%s/foo/bar/g # Ersetze "foo" durch "bar" in allen Zeilen - :s/foo/bar/g # Ersetze "foo" durch "bar" in der aktuellen Zeile - :%s/\n/\r/g # Ersetze das newline-Zeichen bei allen Zeilen durch - # ein carriage return - - # Zu einzelnen Zeichen springen - - f # Springe vorwärts und auf dem Zeichen - t # Springe vorwärts und lande vor dem Zeichen - - # Zum Beispiel, - f< # Springe vorwärts und lande auf < - t< # Springe vorwärts und lande vor < - - # Wortweise navigieren - - w # Springe um ein Wort vorwärts - b # Gehe ein Wort zurück - e # Springe zum Ende des aktuellen Wortes - - # Weitere Befehle, um zu navigieren - - gg # Gehe an den Start der Datei - G # Gehe an das Ende der Datei - :NUM # Springe zur Zeile NUM (NUM kann eine beliebige Zahl sein) - H # Navigiere zum Start der aktuellen Bildschirmanzeige - M # Navigiere in die Mitte der aktuellen Bildschirmanzeige - L # Navigiere an das Ende der aktuellen Bildschirmanzeige +vim # Öffne in Vim +:help # Öffne die eingebaute Hilfe zum Thema , wenn +# es existiert +:q # Schließe vim +:w # Speichere diese Datei +:wq # Speichere diese Datei und schließe vim +ZZ # Speichere diese Datei und schließe vim +:q! # Schließe vim ohne die Datei zu speichern +# ! *zwingt* die Ausführung von :q, +# daher wird die Datei nicht gespeichert. +ZQ # Beende vim ohne die Datei zu speichern +:x # Speichere die Datei und beende vim +# Dies ist eine kürzere Version von :wq + +u # Änderung rückgängig machen +CTRL+R # Änderung wiederherstellen + +h # Den Cursor um ein Zeichen nach links bewegen +j # Den Cursor eine Zeile nach unten bewegen +k # Den Cursor eine Zeile nach oben bewegen +l # Den Cursor um ein Zeichen nach rechts bewegen + +Ctrl+B # Gehe eine Bildschirmanzeige zurück +Ctrl+F # Gehe eine Bildschirmanzeige vorwärts +Ctrl+D # Gehe eine halbe Bildschirmanzeige vorwärts +Ctrl+U # Gehe eine halbe Bildschirmanzeige zurück + +# Navigieren innerhalb einer Zeile + +0 # Navigiere zum Anfang der Zeile +$ # Navigiere zum Ende der Zeile +^ # Navigiere zum ersten Zeichen, welches kein Leerzeichen ist + +# Im Text suchen + +/word # Hebt alle Ergebnisse nach dem Cursor hervor +?word # Hebt alle Ergebnisse vor dem Cursor hervor +n # Bewegt den Cursor zum nächsten Ergebnis nach der Suche +N # Bewegt den Cursor zum vorherigen Ergebnis der Suche + +:%s/foo/bar/g # Ersetze "foo" durch "bar" in allen Zeilen +:s/foo/bar/g # Ersetze "foo" durch "bar" in der aktuellen Zeile +:%s/\n/\r/g # Ersetze das newline-Zeichen bei allen Zeilen durch +# ein carriage return + +# Zu einzelnen Zeichen springen + +f # Springe vorwärts und auf dem Zeichen +t # Springe vorwärts und lande vor dem Zeichen + +# Zum Beispiel, +f< # Springe vorwärts und lande auf < +t< # Springe vorwärts und lande vor < + +# Wortweise navigieren + +w # Springe um ein Wort vorwärts +b # Gehe ein Wort zurück +e # Springe zum Ende des aktuellen Wortes + +# Weitere Befehle, um zu navigieren + +gg # Gehe an den Start der Datei +G # Gehe an das Ende der Datei +:NUM # Springe zur Zeile NUM (NUM kann eine beliebige Zahl sein) +H # Navigiere zum Start der aktuellen Bildschirmanzeige +M # Navigiere in die Mitte der aktuellen Bildschirmanzeige +L # Navigiere an das Ende der aktuellen Bildschirmanzeige ``` ## Hilfsdokumente: @@ -110,22 +110,22 @@ Vim basiert auf dem Konzept von **modes**. - Ex Mode - Wird verwendet, um im ':'-Prompt Befehle einzugeben ``` - i # Führt vim in den Insert Mode, vor der Cursorposition - a # Führt vim in den Insert Mode, nach der Cursorposition - v # Führt vim in den Visual Mode - : # Führt vim in den Ex Mode - # Führt zurück in den Command Mode, egal in welchem Mode - # man sich gerade befindet. - - # Kopieren und einfügen von Text - - y # Kopiere alles, was im Moment ausgewählt ist - yy # Kopiert die aktuelle Zeile - d # Löscht alles, was im Moment ausgewählt ist - dd # Löscht die aktuelle Zeile - p # Fügt den kopierten Text nach dem Cursor ein - P # Fügt den kopierten Text vor dem Cursor ein - x # Löscht das Zeichen unter dem Cursor +i # Führt vim in den Insert Mode, vor der Cursorposition +a # Führt vim in den Insert Mode, nach der Cursorposition +v # Führt vim in den Visual Mode +: # Führt vim in den Ex Mode + # Führt zurück in den Command Mode, egal in welchem Mode +# man sich gerade befindet. + +# Kopieren und einfügen von Text + +y # Kopiere alles, was im Moment ausgewählt ist +yy # Kopiert die aktuelle Zeile +d # Löscht alles, was im Moment ausgewählt ist +dd # Löscht die aktuelle Zeile +p # Fügt den kopierten Text nach dem Cursor ein +P # Fügt den kopierten Text vor dem Cursor ein +x # Löscht das Zeichen unter dem Cursor ``` ## Die 'Grammatik' von Vim @@ -140,68 +140,68 @@ Vim kann als Satz von Kommandos angesehen werden, welche im Format Einige wichtige Beispiele von 'Verb', 'Modifier' und 'Nouns': ``` - # 'Verb' - - d # löschen - c # ändern - y # kopieren - v # visuelles auswählen - - # 'Modifiers' - - i # innerhalb - a # außerhalb - NUM # Nummer (NUM kann irgendeine Zahl sein) - f # Sucht nach etwas und landet darauf - t # Sucht nach etwas und stoppt davor - / # Suche eine Zeichenfolge ab dem Cursor - ? # Suche eine Zeichenfolge vor dem Cursor - - # 'Nouns' - - w # Wort - s # Satz - p # Abschnitt - b # Block - - # Beispielsätze resp. Kommandos - - d2w # lösche zwei Wörter - cis # Ändere innerhalb des Satzes. - yip # Kopiere innerhalb des Abschnitts (kopiere den Abschnitt, - # in welchem du bist) - ct< # Ändere bis zur spitzen Klammer - # Ändere den Text von deiner aktuellen Cursorposition bis - # zur nächsten spitzen Klammer - d$ # Lösche bis zum Ende der Zeile +# 'Verb' + +d # löschen +c # ändern +y # kopieren +v # visuelles auswählen + +# 'Modifiers' + +i # innerhalb +a # außerhalb +NUM # Nummer (NUM kann irgendeine Zahl sein) +f # Sucht nach etwas und landet darauf +t # Sucht nach etwas und stoppt davor +/ # Suche eine Zeichenfolge ab dem Cursor +? # Suche eine Zeichenfolge vor dem Cursor + +# 'Nouns' + +w # Wort +s # Satz +p # Abschnitt +b # Block + +# Beispielsätze resp. Kommandos + +d2w # lösche zwei Wörter +cis # Ändere innerhalb des Satzes. +yip # Kopiere innerhalb des Abschnitts (kopiere den Abschnitt, +# in welchem du bist) +ct< # Ändere bis zur spitzen Klammer +# Ändere den Text von deiner aktuellen Cursorposition bis +# zur nächsten spitzen Klammer +d$ # Lösche bis zum Ende der Zeile ``` ## Einige Shortcuts und Tricks ``` - > # Rücke die Auswahl um einen Block ein - < # Lösche eine Einrückung der Auswahl - :earlier 15m # Stellt das Dokument so wieder her, wie es vor 15 - # Minuten war - :later 15m # den oberen Befehl rückgängig machen - ddp # Vertauschen zweier aufeinanderfolgenden Zeilen - # Zuerst dd, dann p - . # Wiederhole die vorherige Aktion - :w !sudo tee % # Speichere die Datei als Root - :set syntax=c # Stelle das Syntax-Highlighting für 'C' ein - :sort # Alle Zeilen sortieren - :sort! # Alle Zeilen rückwärts sortieren - :sort u # Alle Zeilen sortieren und Duplikate entfernen - ~ # Umschalten der Groß-/Kleinschreibung des ausgewählten Textes - u # Ausgewählten Text zu Kleinschreibung ändern - U # Ausgewählten Text zu Großschreibung ändern - - # Text-Folding (Textfaltung) - zf # Erstelle eine Faltung des ausgewählten Textes - zo # Öffne die aktuelle Faltung - zc # Schließe die aktuelle Faltung - zR # Öffne alle Faltungen - zM # Schließe alle Faltungen +> # Rücke die Auswahl um einen Block ein +< # Lösche eine Einrückung der Auswahl +:earlier 15m # Stellt das Dokument so wieder her, wie es vor 15 +# Minuten war +:later 15m # den oberen Befehl rückgängig machen +ddp # Vertauschen zweier aufeinanderfolgenden Zeilen +# Zuerst dd, dann p +. # Wiederhole die vorherige Aktion +:w !sudo tee % # Speichere die Datei als Root +:set syntax=c # Stelle das Syntax-Highlighting für 'C' ein +:sort # Alle Zeilen sortieren +:sort! # Alle Zeilen rückwärts sortieren +:sort u # Alle Zeilen sortieren und Duplikate entfernen +~ # Umschalten der Groß-/Kleinschreibung des ausgewählten Textes +u # Ausgewählten Text zu Kleinschreibung ändern +U # Ausgewählten Text zu Großschreibung ändern + +# Text-Folding (Textfaltung) +zf # Erstelle eine Faltung des ausgewählten Textes +zo # Öffne die aktuelle Faltung +zc # Schließe die aktuelle Faltung +zR # Öffne alle Faltungen +zM # Schließe alle Faltungen ``` ## Makros @@ -212,9 +212,9 @@ Kommandos, welche du braucht, aufgenommen bis die Aufnahme gestoppt wird. Wenn du ein Makro ausführst, werden exakt die gleichen Schritte gemacht. ``` - qa # Starte das Aufnehmen des Makros 'a' - q # Beende das Aufnehmen - @a # Führe das Makro 'a' aus +qa # Starte das Aufnehmen des Makros 'a' +q # Beende das Aufnehmen +@a # Führe das Makro 'a' aus ``` ### Konfigurieren mit ~/.vimrc -- cgit v1.2.3 From 07ec65627438412c973209d8c489ef21ef16fb4a Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Mon, 14 Nov 2022 12:24:52 +0100 Subject: correct/reinstall indentations There were a few 'false positives' applying sed's rule to remove leading spaces. This commit corrects this. --- de-de/vim-de.html.markdown | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/de-de/vim-de.html.markdown b/de-de/vim-de.html.markdown index 707bae5b..70082feb 100644 --- a/de-de/vim-de.html.markdown +++ b/de-de/vim-de.html.markdown @@ -13,26 +13,25 @@ filename: LearnVim-de.txt [Vim](http://www.vim.org) (Vi IMproved) ist ein Klon von vi, dem bekannten Editor für Unix. Es ist ein Texteditor, welcher mit Fokus auf Geschwindigkeit und Prouktivität entwickelt -wurde. -Vim hat viele Keybindings für ein schnelles navigieren und schnelles bearbeiten -einer Datei. +wurde. Vim hat viele Keybindings für ein schnelles navigieren und schnelles +bearbeiten einer Datei. ## Grundlagen, um in Vim zu navigieren ``` vim # Öffne in Vim :help # Öffne die eingebaute Hilfe zum Thema , wenn -# es existiert + # es existiert :q # Schließe vim :w # Speichere diese Datei :wq # Speichere diese Datei und schließe vim ZZ # Speichere diese Datei und schließe vim :q! # Schließe vim ohne die Datei zu speichern -# ! *zwingt* die Ausführung von :q, -# daher wird die Datei nicht gespeichert. + # ! *zwingt* die Ausführung von :q, + # daher wird die Datei nicht gespeichert. ZQ # Beende vim ohne die Datei zu speichern :x # Speichere die Datei und beende vim -# Dies ist eine kürzere Version von :wq + # Dies ist eine kürzere Version von :wq u # Änderung rückgängig machen CTRL+R # Änderung wiederherstellen @@ -63,7 +62,7 @@ N # Bewegt den Cursor zum vorherigen Ergebnis der Suche :%s/foo/bar/g # Ersetze "foo" durch "bar" in allen Zeilen :s/foo/bar/g # Ersetze "foo" durch "bar" in der aktuellen Zeile :%s/\n/\r/g # Ersetze das newline-Zeichen bei allen Zeilen durch -# ein carriage return + # ein carriage return # Zu einzelnen Zeichen springen @@ -115,7 +114,7 @@ a # Führt vim in den Insert Mode, nach der Cursorposition v # Führt vim in den Visual Mode : # Führt vim in den Ex Mode # Führt zurück in den Command Mode, egal in welchem Mode -# man sich gerade befindet. + # man sich gerade befindet. # Kopieren und einfügen von Text @@ -169,10 +168,10 @@ b # Block d2w # lösche zwei Wörter cis # Ändere innerhalb des Satzes. yip # Kopiere innerhalb des Abschnitts (kopiere den Abschnitt, -# in welchem du bist) + # in welchem du bist) ct< # Ändere bis zur spitzen Klammer -# Ändere den Text von deiner aktuellen Cursorposition bis -# zur nächsten spitzen Klammer + # Ändere den Text von deiner aktuellen Cursorposition bis + # zur nächsten spitzen Klammer d$ # Lösche bis zum Ende der Zeile ``` @@ -181,11 +180,10 @@ d$ # Lösche bis zum Ende der Zeile ``` > # Rücke die Auswahl um einen Block ein < # Lösche eine Einrückung der Auswahl -:earlier 15m # Stellt das Dokument so wieder her, wie es vor 15 -# Minuten war +:earlier 15m # Stellt das Dokument so wieder her, wie es vor 15 Minuten war :later 15m # den oberen Befehl rückgängig machen ddp # Vertauschen zweier aufeinanderfolgenden Zeilen -# Zuerst dd, dann p + # Zuerst dd, dann p . # Wiederhole die vorherige Aktion :w !sudo tee % # Speichere die Datei als Root :set syntax=c # Stelle das Syntax-Highlighting für 'C' ein -- cgit v1.2.3 From df4dacd110bc69aec68ad5d4487981c0c4c233a4 Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Mon, 14 Nov 2022 12:28:17 +0100 Subject: A spellcheck --- de-de/vim-de.html.markdown | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/de-de/vim-de.html.markdown b/de-de/vim-de.html.markdown index 70082feb..8aeddeb4 100644 --- a/de-de/vim-de.html.markdown +++ b/de-de/vim-de.html.markdown @@ -12,7 +12,7 @@ filename: LearnVim-de.txt [Vim](http://www.vim.org) (Vi IMproved) ist ein Klon von vi, dem bekannten Editor für Unix. Es ist ein -Texteditor, welcher mit Fokus auf Geschwindigkeit und Prouktivität entwickelt +Texteditor, welcher mit Fokus auf Geschwindigkeit und Produktivität entwickelt wurde. Vim hat viele Keybindings für ein schnelles navigieren und schnelles bearbeiten einer Datei. @@ -97,7 +97,6 @@ Zum Beispiel öffnet `:help navigation` die Dokumentation über das Navigieren `:help` kann auch ohne ein Argument verwendet werden. Dies zeigt den Standard- Hilfsdialog an, welcher den Start mit vim einfacher macht. -that aims to make getting started with vim more approachable! ## Modi: -- cgit v1.2.3 From 437ebf772b4e3688f4cb98b3f29cc472e6fdf35b Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Mon, 14 Nov 2022 12:33:52 +0100 Subject: use markdownlint for additional improvements Accounts for a selection of issues identified by markdownlint.[1] [1] https://github.com/markdownlint/markdownlint, version 0.12.0. --- de-de/vim-de.html.markdown | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/de-de/vim-de.html.markdown b/de-de/vim-de.html.markdown index 8aeddeb4..f3dd12e5 100644 --- a/de-de/vim-de.html.markdown +++ b/de-de/vim-de.html.markdown @@ -9,7 +9,6 @@ translators: filename: LearnVim-de.txt --- - [Vim](http://www.vim.org) (Vi IMproved) ist ein Klon von vi, dem bekannten Editor für Unix. Es ist ein Texteditor, welcher mit Fokus auf Geschwindigkeit und Produktivität entwickelt @@ -41,9 +40,9 @@ j # Den Cursor eine Zeile nach unten bewegen k # Den Cursor eine Zeile nach oben bewegen l # Den Cursor um ein Zeichen nach rechts bewegen -Ctrl+B # Gehe eine Bildschirmanzeige zurück -Ctrl+F # Gehe eine Bildschirmanzeige vorwärts -Ctrl+D # Gehe eine halbe Bildschirmanzeige vorwärts +Ctrl+B # Gehe eine Bildschirmanzeige zurück +Ctrl+F # Gehe eine Bildschirmanzeige vorwärts +Ctrl+D # Gehe eine halbe Bildschirmanzeige vorwärts Ctrl+U # Gehe eine halbe Bildschirmanzeige zurück # Navigieren innerhalb einer Zeile @@ -89,7 +88,7 @@ M # Navigiere in die Mitte der aktuellen Bildschirmanzeige L # Navigiere an das Ende der aktuellen Bildschirmanzeige ``` -## Hilfsdokumente: +## Hilfsdokumente Vim hat eine eingebaute Dokumentation, welche mit `:help ` aufgerufen werden kann. @@ -98,13 +97,13 @@ Zum Beispiel öffnet `:help navigation` die Dokumentation über das Navigieren `:help` kann auch ohne ein Argument verwendet werden. Dies zeigt den Standard- Hilfsdialog an, welcher den Start mit vim einfacher macht. -## Modi: +## Modi Vim basiert auf dem Konzept von **modes**. -- Command Mode - Vim startet in diesem Modus, hier kann man navigieren und Befehle eingeben +- Command Mode - Vim erster Modus, hier kann man navigieren und Befehle eingeben - Insert Mode - Wird verwendet, um Änderungen in der Datei zu machen. -- Visual Mode - Wird verwendet, um Text zu markieren und Operationen durchzuführen +- Visual Mode - Wird verwendet, um Text zu markieren und diesen zu verändern - Ex Mode - Wird verwendet, um im ':'-Prompt Befehle einzugeben ``` -- cgit v1.2.3 From 0cdb0f0c065d961ff612171a60daddbfbcf5d23f Mon Sep 17 00:00:00 2001 From: nbehrnd Date: Mon, 14 Nov 2022 12:54:14 +0100 Subject: Update vim-de.html.markdown --- de-de/vim-de.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/de-de/vim-de.html.markdown b/de-de/vim-de.html.markdown index f3dd12e5..d0b4eb9d 100644 --- a/de-de/vim-de.html.markdown +++ b/de-de/vim-de.html.markdown @@ -101,7 +101,7 @@ Hilfsdialog an, welcher den Start mit vim einfacher macht. Vim basiert auf dem Konzept von **modes**. -- Command Mode - Vim erster Modus, hier kann man navigieren und Befehle eingeben +- Command Mode - Vims erster Modus, hier kann man navigieren und Befehle eingeben - Insert Mode - Wird verwendet, um Änderungen in der Datei zu machen. - Visual Mode - Wird verwendet, um Text zu markieren und diesen zu verändern - Ex Mode - Wird verwendet, um im ':'-Prompt Befehle einzugeben -- cgit v1.2.3 From 847f5c22590cf6ec6401caf31c2b1744cb67ae1a Mon Sep 17 00:00:00 2001 From: Alexander Hecke <26191361+heckelson@users.noreply.github.com> Date: Tue, 15 Nov 2022 10:29:45 +0100 Subject: Remove dead link --- hy.html.markdown | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hy.html.markdown b/hy.html.markdown index 1287095f..f6bdead0 100644 --- a/hy.html.markdown +++ b/hy.html.markdown @@ -13,8 +13,7 @@ hy to call native python code or python to call native hy code as well This tutorial works for hy ≥ 0.9.12, with some corrections for hy 0.11. ```clojure -;; this gives an gentle introduction to hy for a quick trial head to -;; http://try-hy.appspot.com +;; this gives an gentle introduction to hy ;; ; Semicolon comments, like other LISPS -- cgit v1.2.3 From 155ed84239fd5064dc7238fa054c8688dedd5c73 Mon Sep 17 00:00:00 2001 From: Kemel Zaidan Date: Wed, 16 Nov 2022 11:38:26 -0300 Subject: Update processing-pt.html.markdown Fixing a typo to capital letter since it refers to the language name --- pt-br/processing-pt.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pt-br/processing-pt.html.markdown b/pt-br/processing-pt.html.markdown index 229aec07..b9b5b4ea 100644 --- a/pt-br/processing-pt.html.markdown +++ b/pt-br/processing-pt.html.markdown @@ -171,7 +171,7 @@ float sr = sqrt(25); // sr = 5.0 // aqui. (https://processing.org/reference/PVector.html) // Trigonometria -// O processamento também suporta operações trigonométricas fornecendo um +// O Processamento também suporta operações trigonométricas fornecendo um // conjunto de funções. sin(), cos(), tan(), asin(), acos(), atan() e também // degrees() e radians() para conversão conveniente. // No entanto, essas funções usam o ângulo em radianos como parâmetro, então é @@ -476,4 +476,4 @@ e até mesmo suas próprias aulas. (Confie em mim! O processamento de projetos p ## Alguns recursos úteis - [Site do Processing](http://processing.org) - - [Sketches em Processing](http://openprocessing.org) \ No newline at end of file + - [Sketches em Processing](http://openprocessing.org) -- cgit v1.2.3 From f1c573417500e13c9aab7590e1e3873b7262b8d4 Mon Sep 17 00:00:00 2001 From: Kemel Zaidan Date: Wed, 16 Nov 2022 11:46:14 -0300 Subject: Update processing-pt.html.markdown Fixing some translation errors --- pt-br/processing-pt.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pt-br/processing-pt.html.markdown b/pt-br/processing-pt.html.markdown index b9b5b4ea..880e1377 100644 --- a/pt-br/processing-pt.html.markdown +++ b/pt-br/processing-pt.html.markdown @@ -171,7 +171,7 @@ float sr = sqrt(25); // sr = 5.0 // aqui. (https://processing.org/reference/PVector.html) // Trigonometria -// O Processamento também suporta operações trigonométricas fornecendo um +// O Processing também suporta operações trigonométricas fornecendo um // conjunto de funções. sin(), cos(), tan(), asin(), acos(), atan() e também // degrees() e radians() para conversão conveniente. // No entanto, essas funções usam o ângulo em radianos como parâmetro, então é @@ -293,7 +293,7 @@ arc(x, y, largura, altura, inicio, fim, [modo]); // CHORD porém sem contorno // Curvas -// O processamento fornece duas implementações de curvas; usando curve() e +// O Processing fornece duas implementações de curvas; usando curve() e // bezier(). Como pretendo manter isso simples, não vou discutir mais detalhes. // No entanto, se você quiser implementá-lo em seu sketch, aqui estão as // referências: (https://processing.org/reference/curve_.html) -- cgit v1.2.3 From a4a507bef1249840b3ed44aca018ff2234f2457c Mon Sep 17 00:00:00 2001 From: Kemel Zaidan Date: Wed, 16 Nov 2022 11:52:34 -0300 Subject: Update processing-pt.html.markdown Last typo changes left --- pt-br/processing-pt.html.markdown | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pt-br/processing-pt.html.markdown b/pt-br/processing-pt.html.markdown index 880e1377..5ed2950a 100644 --- a/pt-br/processing-pt.html.markdown +++ b/pt-br/processing-pt.html.markdown @@ -5,7 +5,7 @@ contributors: - ["Phone Thant Ko", "http://github.com/phonethantko"] - ["Divay Prakash", "https://github.com/divayprakash"] translators: - - ["Kemel Zaidan", "https://github.com/kemelzaidan"] + - ["Kemel Zaidan", "https://github.com/kemelzaidan"] lang: pt-br --- @@ -19,7 +19,8 @@ Embora a linguagem seja baseada na linguagem Java, sua sintaxe foi amplamente influenciado por ambas as sintaxes Java e Javascript. [Veja mais aqui](https://processing.org/reference/) -A linguagem é tipada estaticamente e também vem com a sua IDE oficial para +A linguagem é tipada estaticamente e também vem com o seu Ambiente de Desenvolvimento +Integrado (do inglês Integrated Development Environment - IDE) oficial para compilar e executar os scripts. ``` @@ -47,7 +48,7 @@ compilar e executar os scripts. // Observação! A sintaxe é muito semelhante à do C++. void setup() { // Isso imprime a saída clássica "Hello World!" no console quando executado. - println("Olá Mundo!"); // Outra linguagem cilada para ponto e vírgula, não é? + println("Olá Mundo!"); // Mais uma linguagem com esse maldito ponto e vírgula, não é? } // Normalmente, colocamos todos os códigos estáticos dentro do método setup() @@ -244,7 +245,7 @@ exit(); // Isso para o programa. É útil para programas com draw() ## Desenho com Processing Como você já deve ter entendido o básico da linguagem, vamos agora -veja a melhor parte do Processing - DESENHAR. +ver a melhor parte do Processing - DESENHAR. ``` /* ------ @@ -378,9 +379,9 @@ stroke(255, 255, 0, 200); // cor do traço definida para amarelo com transparên // definido para um valor menor. // Imagens -// O processamento pode renderizar imagens e usá-las de várias maneiras. +// O Processing pode renderizar imagens e usá-las de várias maneiras. // Principalmente armazenado como Tipo de dados PImage. -filter(sombreador); // O processamento suporta várias funções de filtro para manipulação de imagens. +filter(sombreador); // O Processing suporta várias funções de filtro para manipulação de imagens. texture(imagem); // PImage pode ser passado em argumentos para mapeamento de textura das formas. ``` @@ -466,12 +467,12 @@ void branch(float len) { } ``` -O processamento é fácil de aprender e é particularmente útil para criar +A linguagem Processing é fácil de aprender e é particularmente útil para criar conteúdo (mesmo em 3D) sem ter que digitar muitos códigos. É tão simples que você pode ler o código e ter uma ideia aproximada do fluxo do programa. No entanto, isso não se aplica quando você introduz bibliotecas externas, pacotes -e até mesmo suas próprias aulas. (Confie em mim! O processamento de projetos pode ficar realmente monstruoso...) +e até mesmo suas próprias aulas. (Confie em mim! Projetos em processing podem ficar realmente monstruosos...) ## Alguns recursos úteis -- cgit v1.2.3 From 32aad6aaf2a808d0efcb4b2b787db84c31762bda Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Wed, 16 Nov 2022 23:30:30 +0100 Subject: =?UTF-8?q?Fix=20typo:=20sting=20=E2=86=92=20string?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cobol.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cobol.html.markdown b/cobol.html.markdown index 1c858396..1350c66f 100644 --- a/cobol.html.markdown +++ b/cobol.html.markdown @@ -132,7 +132,7 @@ organizations. *Now it is time to learn about two related COBOL verbs: string and unstring. - *The string verb is used to concatenate, or put together, two or more stings. + *The string verb is used to concatenate, or put together, two or more strings. *Unstring is used, not surprisingly, to separate a *string into two or more smaller strings. *It is important that you remember to use ‘delimited by’ when you -- cgit v1.2.3 From d2d10c7050b83f01cd7a37d9f80a13e6c860cff2 Mon Sep 17 00:00:00 2001 From: Louis PORTAY Date: Mon, 21 Nov 2022 14:24:01 +0100 Subject: [yaml/en] add another example for YAML null value --- fr-fr/yaml-fr.html.markdown | 1 + yaml.html.markdown | 1 + 2 files changed, 2 insertions(+) diff --git a/fr-fr/yaml-fr.html.markdown b/fr-fr/yaml-fr.html.markdown index c7cb9421..36c33bd1 100644 --- a/fr-fr/yaml-fr.html.markdown +++ b/fr-fr/yaml-fr.html.markdown @@ -36,6 +36,7 @@ valeur_numérique: 100 notation_scientifique: 1e+12 booléen: true valeur_null: null +une_autre_valeur_null: ~ clé avec espaces: valeur # Bien qu'il ne soit pas nécessaire de mettre les chaînes de caractères # entre guillemets, cela reste possible, et parfois utile. diff --git a/yaml.html.markdown b/yaml.html.markdown index 5c898148..3b40e6a7 100644 --- a/yaml.html.markdown +++ b/yaml.html.markdown @@ -38,6 +38,7 @@ octal_notation: 0123 # evaluates to 83 # If you want it to be interpreted as a boolean, use true. boolean: true null_value: null +another_null_value: ~ key with spaces: value # Yes and No (doesn't matter the case) will be evaluated to boolean -- cgit v1.2.3 From 2a56a9cc5ecd7a4daf6c8b90c2f4ad51d1e75ce2 Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 23 Nov 2022 20:48:05 +0100 Subject: run `sed -i "s/ *$//" awk.html.markdown` Remove of trailing spaces. --- awk.html.markdown | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/awk.html.markdown b/awk.html.markdown index 34013251..55b8e5da 100644 --- a/awk.html.markdown +++ b/awk.html.markdown @@ -118,11 +118,11 @@ BEGIN { # Arrays 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"; @@ -240,7 +240,7 @@ function io_functions( localvar) { # for this can be treated as a file handle, for purposes of I/O. This makes # it feel sort of like shell scripting, but to get the same output, the string # must match exactly, so use a variable: - + outfile = "/tmp/foobar.txt"; print "foobar" > outfile; @@ -261,7 +261,7 @@ function io_functions( localvar) { # Reads a line from a file and stores in localvar infile = "/tmp/foobar.txt"; - getline localvar < infile; + getline localvar < infile; close(infile); } @@ -273,10 +273,10 @@ function io_functions( localvar) { # When you pass arguments to AWK, they are treated as file names to process. # It will process them all, in order. Think of it like an implicit for loop, # iterating over the lines in these files. these patterns and actions are like -# switch statements inside the loop. +# switch statements inside the loop. /^fo+bar$/ { - + # This action will execute for every line that matches the regular # expression, /^fo+bar$/, and will be skipped for any line that fails to # match it. Let's just print the line: @@ -382,5 +382,5 @@ Further Reading: * [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) -* [Awk alpinelinux wiki](https://wiki.alpinelinux.org/wiki/Awk) a technical summary and list of "gotchas" (places where different implementations may behave in different or unexpected ways). +* [Awk alpinelinux wiki](https://wiki.alpinelinux.org/wiki/Awk) a technical summary and list of "gotchas" (places where different implementations may behave in different or unexpected ways). * [basic libraries for awk](https://github.com/dubiousjim/awkenough) -- cgit v1.2.3 From 15c75c28b94d1700d75baba4346e70beb43d8137 Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 23 Nov 2022 20:53:39 +0100 Subject: rm overly long lines, consider markdownlint Lines longer than 80 characters are edited. Within reason, issues identified by markdownlint[1] are equally curated. [1] https://github.com/markdownlint/markdownlint, version 0.12.0 --- awk.html.markdown | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/awk.html.markdown b/awk.html.markdown index 55b8e5da..dc22a2bd 100644 --- a/awk.html.markdown +++ b/awk.html.markdown @@ -123,7 +123,7 @@ BEGIN { n = split("foo:bar:baz", arr, ":"); - # You also have associative arrays (actually, they're all associative arrays) + # You also have associative arrays (indeed, they're all associative arrays) assoc["foo"] = "bar"; assoc["bar"] = "baz"; @@ -216,7 +216,8 @@ function string_functions( localvar, arr) { match(localvar, "t"); # => 4, since the 't' is the fourth character # Split on a delimiter - n = split("foo-bar-baz", arr, "-"); # a[1] = "foo"; a[2] = "bar"; a[3] = "baz"; n = 3 + n = split("foo-bar-baz", arr, "-"); + # result: 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" @@ -238,8 +239,8 @@ function io_functions( localvar) { # 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, but to get the same output, the string - # must match exactly, so use a variable: + # it feel sort of like shell scripting, but to get the same output, the + # string must match exactly, so use a variable: outfile = "/tmp/foobar.txt"; @@ -376,11 +377,15 @@ END { } ``` + 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. +* [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) -* [Awk alpinelinux wiki](https://wiki.alpinelinux.org/wiki/Awk) a technical summary and list of "gotchas" (places where different implementations may behave in different or unexpected ways). +* [Awk alpinelinux wiki](https://wiki.alpinelinux.org/wiki/Awk) a technical + summary and list of "gotchas" (places where different implementations may + behave in different or unexpected ways). * [basic libraries for awk](https://github.com/dubiousjim/awkenough) -- cgit v1.2.3 From 033f3e65b930fbb6b48eb1a931717fed3666ed95 Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 23 Nov 2022 21:01:38 +0100 Subject: run `sed -i "s/ *$//" awk-es.html.markdown` Remove of trailing spaces. --- es-es/awk-es.html.markdown | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/es-es/awk-es.html.markdown b/es-es/awk-es.html.markdown index 2f771320..c5fec19e 100644 --- a/es-es/awk-es.html.markdown +++ b/es-es/awk-es.html.markdown @@ -11,8 +11,8 @@ lang: es-es AWK es una herramienta estándar en cada sistema UNIX compatible con POSIX. Es como un Perl restringido, perfecto para tareas de procesamiento de texto y -otras necesidades de scripting. Tiene una sintaxis similar a C, pero sin -puntos y comas, manejo manual de memoria y tipado estático. Puedes llamarlo +otras necesidades de scripting. Tiene una sintaxis similar a C, pero sin +puntos y comas, manejo manual de memoria y tipado estático. Puedes llamarlo desde un script de shell o usarlo como un lenguaje stand-alone para scripting. ¿Por qué elegir AWK sobre Perl? Principalmente, porque AWK es parte de UNIX. @@ -74,7 +74,7 @@ BEGIN { # Bloques formados por múltiples líneas usan llaves while (a < 10) { - print "La concatenación de strings se hace " " con series " + print "La concatenación de strings se hace " " con series " print " de" " strings separados por espacios" print a @@ -153,12 +153,12 @@ function arithmetic_functions(a, b, c, localvar) { # Todo es global. No es problema en scripts pequeños, pero sí para # scripts más grandes. - # Hay un work-around (mmm... hack). Los argumentos de las funciones son + # Hay un work-around (mmm... hack). Los argumentos de las funciones son # locales para la función, y AWK permite definir más argumentos de función - # de los que necesita, por lo que define las variables locales en la + # de los que necesita, por lo que define las variables locales en la # declaración como en la función de arriba. Como convención, agrega - # espacios en blanco para distinguir los parámetros de la función de las - # variables locales. En este ejemplo, a, b y c son parámetros y localvar es una + # espacios en blanco para distinguir los parámetros de la función de las + # variables locales. En este ejemplo, a, b y c son parámetros y localvar es una # variable local. # Ahora, a demostrar las funciones aritméticas @@ -222,8 +222,8 @@ function io_functions( localvar) { # También hay printf printf("%s %d %d %d\n", "Testing", 1, 2, 3) - # AWK no tiene handles de archivos en sí mismo. Automáticamente abrirá un - # handle de archivo cuando use algo que necesite uno. El string que usaste + # AWK no tiene handles de archivos en sí mismo. Automáticamente abrirá un + # handle de archivo cuando use algo que necesite uno. El string que usaste # para esto puede ser tratada como un handle de archivo para propósitos de I/O. # Esto lo hace similar al scripting de shell: @@ -247,17 +247,17 @@ function io_functions( localvar) { close("/tmp/foobar.txt") } -# Como dije al inicio, los programas en AWK son una colección de patrones y +# Como dije al inicio, los programas en AWK son una colección de patrones y # acciones. Ya conociste el patrón BEGIN. otros patrones sólo se usan si estás # procesando líneas desde archivos o stdin. -# Cuando pasas argumentos a AWK, son tratados como nombres de archivos a -# procesar. Los va a procesar todos, en orden. Imagínalos como un ciclo for +# Cuando pasas argumentos a AWK, son tratados como nombres de archivos a +# procesar. Los va a procesar todos, en orden. Imagínalos como un ciclo for # implícito, iterando sobre las líneas de estos archivos. Estos patrones y # acciones son como instrucciones switch dentro del ciclo. /^fo+bar$/ { - + # Esta acción se ejecutará por cada línea que haga match con la expresión # regular /^fo+bar$/, y será saltada por cualquier línea que no haga match. # Vamos a sólo mostrar la línea: @@ -268,7 +268,7 @@ function io_functions( localvar) { # $0 es el nombre de la línea actual que se está procesando. # Se crea automáticamente para ti. - # Probablemente puedas adivinar que hay otras variables $. Cada línea es + # Probablemente puedas adivinar que hay otras variables $. Cada línea es # separada implícitamente antes de que se llame cada acción, justo como lo # hace shell. Y, como shell, cada campo puede ser accesado con $. @@ -301,7 +301,7 @@ a > 0 { # Y ya te das una idea. Procesar archivos de texto, leyendo una línea a la vez, # y haciendo algo con ella, particularmente separando en un deliminator, es tan # común en UNIX que AWK es un lenguaje de scripting que hace todo eso por ti -# sin que tengas que pedirlo. Basta con escribir los patrones y acciones +# sin que tengas que pedirlo. Basta con escribir los patrones y acciones # basados en lo que esperas de la entrada y lo quieras quieras hacer con ella. # Aquí está un ejemplo de un script simple, para lo que AWK es perfecto. @@ -343,7 +343,7 @@ $1 == name { nlines++ } -# Otro patrón especial es END. Va a ejecutarse después de procesar todos los +# Otro patrón especial es END. Va a ejecutarse después de procesar todos los # archivos de texto. A diferencia de BEGIN, sólo se ejecuta si le das dado una # entrada a procesar. Se ejecutará después de que todos los archivos hayan sido # leídos y procesados según las reglas y acciones que programaste. El propósito -- cgit v1.2.3 From 5260db7077d839da6bb94e9bb5c1857a3498d7b6 Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 23 Nov 2022 21:04:56 +0100 Subject: substitute a tab space by explicit spaces --- es-es/awk-es.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es-es/awk-es.html.markdown b/es-es/awk-es.html.markdown index c5fec19e..25c40ca4 100644 --- a/es-es/awk-es.html.markdown +++ b/es-es/awk-es.html.markdown @@ -75,7 +75,7 @@ BEGIN { # Bloques formados por múltiples líneas usan llaves while (a < 10) { print "La concatenación de strings se hace " " con series " - print " de" " strings separados por espacios" + print " de" " strings separados por espacios" print a a++ -- cgit v1.2.3 From 2ad6b09fa9cbc693bceb6b4abe14599b425f1998 Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 23 Nov 2022 21:08:20 +0100 Subject: edit overly long lines, consider markdownlint Lines longer than 80 characters are edited. Withn reason, suggests by markdownlint[1] are equally considered, too. [1] https://github.com/markdownlint/markdownlint, version 0.12.0. --- es-es/awk-es.html.markdown | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/es-es/awk-es.html.markdown b/es-es/awk-es.html.markdown index 25c40ca4..725dae1d 100644 --- a/es-es/awk-es.html.markdown +++ b/es-es/awk-es.html.markdown @@ -158,8 +158,8 @@ function arithmetic_functions(a, b, c, localvar) { # de los que necesita, por lo que define las variables locales en la # declaración como en la función de arriba. Como convención, agrega # espacios en blanco para distinguir los parámetros de la función de las - # variables locales. En este ejemplo, a, b y c son parámetros y localvar es una - # variable local. + # variables locales. En este ejemplo, a, b y c son parámetros y localvar es + # una variable local. # Ahora, a demostrar las funciones aritméticas @@ -224,8 +224,8 @@ function io_functions( localvar) { # AWK no tiene handles de archivos en sí mismo. Automáticamente abrirá un # handle de archivo cuando use algo que necesite uno. El string que usaste - # para esto puede ser tratada como un handle de archivo para propósitos de I/O. - # Esto lo hace similar al scripting de shell: + # para esto puede ser tratada como un handle de archivo para propósitos + # de I/O. Esto lo hace similar al scripting de shell: print "foobar" >"/tmp/foobar.txt" @@ -356,8 +356,10 @@ END { } ``` + Más información: * [Tutorial de AWK](http://www.grymoire.com/Unix/Awk.html) * [Página man de AWK](https://linux.die.net/man/1/awk) -* [La guía del usuario de GNU Awk](https://www.gnu.org/software/gawk/manual/gawk.html): GNU Awk se encuentra en la mayoría de los sistemas Linux. +* [La guía del usuario de GNU Awk](https://www.gnu.org/software/gawk/manual/gawk.html): + GNU Awk se encuentra en la mayoría de los sistemas Linux. -- cgit v1.2.3 From 38abd4298cd25bd1a2ed9efd09df51766c97ae27 Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 23 Nov 2022 21:17:18 +0100 Subject: run `sed -i 's/ *$//' awk-fr.html.markdown` Remove of trailing spaces. --- fr-fr/awk-fr.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fr-fr/awk-fr.html.markdown b/fr-fr/awk-fr.html.markdown index 9e45a89b..fa4c36cc 100644 --- a/fr-fr/awk-fr.html.markdown +++ b/fr-fr/awk-fr.html.markdown @@ -53,7 +53,7 @@ BEGIN { # Les variables sont globales. Pas besoin de les déclarer. count = 0; - # les opérateurs sont identiques au langage C et aux langages similaires + # les opérateurs sont identiques au langage C et aux langages similaires # (tels que C#, C++, etc.) a = count + 1; # addition b = count - 1; # soustraction -- cgit v1.2.3 From 27f052e68d1132796b7fcf3deed61dfe937193ee Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 23 Nov 2022 21:26:20 +0100 Subject: break overly long lines Critical threshold for a line are 80 characters maximum. --- fr-fr/awk-fr.html.markdown | 54 ++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/fr-fr/awk-fr.html.markdown b/fr-fr/awk-fr.html.markdown index fa4c36cc..172a3ba4 100644 --- a/fr-fr/awk-fr.html.markdown +++ b/fr-fr/awk-fr.html.markdown @@ -73,7 +73,8 @@ BEGIN { a++; b--; - # En tant qu'opérateur préfixé, c'est la valeur incrémentée qui est retournée + # En tant qu'opérateur préfixé, c'est la valeur incrémentée qui + # est retournée ++a; --b; @@ -155,7 +156,8 @@ BEGIN { delete ARGV[1]; - # Le nombre d'arguments de la ligne de commande est assigné à la variable ARGC + # Le nombre d'arguments de la ligne de commande est assigné à + # la variable ARGC print ARGC; # AWK inclue trois catégories de fonction. @@ -175,11 +177,11 @@ function arithmetic_functions(a, b, c, d) { # Il y a cependant une solution de contournement (enfin ... une bidouille). # Les arguments d'une fonction sont locaux à cette fonction. - # Et AWK vous permet de définir plus d'arguments à la fonction que nécessaire. - # Il suffit donc de mettre une variable locale dans la déclaration de fonction, - # comme ci-dessus. La convention veut que vous mettiez quelques espaces - # supplémentaires pour faire la distinction entre les paramètres réels et - # les variables locales. + # Et AWK vous permet de définir plus d'arguments à la fonction que + # nécessaire. Il suffit donc de mettre une variable locale dans la + # déclaration de fonction, comme ci-dessus. La convention veut que vous + # mettiez quelques espaces supplémentaires pour faire la distinction entre + # les paramètres réels et les variables locales. # Dans cet exemple, a, b et c sont des paramètres réels, # alors que d est simplement une variable locale. @@ -225,12 +227,14 @@ function string_functions( localvar, arr) { sub("fo+", "Meet me at the ", localvar); # localvar => "Meet me at the bar" gsub("e", ".", localvar); # localvar => "m..t m. at th. bar" - # Rechercher une chaîne de caractères qui correspond à une expression régulière - # index() fait la même chose, mais n'autorise pas les expressions régulières + # Rechercher une chaîne de caractères qui correspond à une expression + # régulière index() fait la même chose, mais n'autorise pas les expressions + # régulières match(localvar, "t"); # => 4, puisque 't' est le quatrième caractère # Séparer par un délimiteur - n = split("foo-bar-baz", arr, "-"); # a[1] = "foo"; a[2] = "bar"; a[3] = "baz"; n = 3 + n = split("foo-bar-baz", arr, "-"); + # résultat : a[1] = "foo"; a[2] = "bar"; a[3] = "baz"; n = 3 # Autre astuces utiles sprintf("%s %d %d %d", "Testing", 1, 2, 3); # => "Testing 1 2 3" @@ -259,15 +263,15 @@ function io_functions( localvar) { print "foobar" > outfile; - # Maintenant, la chaîne de caractères "outfile" est un descripteur de fichier. - # Vous pouvez le fermer + # Maintenant, la chaîne de caractères "outfile" est un descripteur de + # fichier. Vous pouvez le fermer close(outfile); # Voici comment exécuter quelque chose dans le shell system("echo foobar"); # => affiche foobar - # Lire quelque chose depuis l'entrée standard et la stocker dans une variable - # locale + # Lire quelque chose depuis l'entrée standard et la stocker dans une + # variable locale getline localvar; # Lire quelque chose à partir d'un pipe (encore une fois, utilisez une @@ -299,12 +303,13 @@ function io_functions( localvar) { print; # Pas d'argument ! C'est parce que print a un défaut : $0. - # $0 est le nom de la ligne en cours de traitement. Il est créé automatiquement. + # $0 est le nom de la ligne en cours de traitement. Il est créé + # automatiquement. # Vous devinez probablement qu'il existe d'autres variables $. - # Chaque ligne est divisée implicitement avant que chaque action soit exécutée, - # comme le fait le shell. Et, comme le shell, chaque champ est accessible - # avec un signe dollar + # Chaque ligne est divisée implicitement avant que chaque action soit + # exécutée, comme le fait le shell. Et, comme le shell, chaque champ est + # accessible avec un signe dollar. # Ceci affichera les deuxième et quatrième champs de la ligne. print $2, $4; @@ -364,22 +369,24 @@ BEGIN { # Premièrement, on demande à l'utilisateur le prénom voulu print "Pour quel prénom voudriez vous savoir l'age moyen ?"; - # On récupère la ligne à partir de l'entrée standard, pas de la ligne de commande + # On récupère la ligne à partir de l'entrée standard, pas de la ligne + # de commande : getline name < "/dev/stdin"; } # Maintenant, pour chaque ligne dont le premier champ est le prénom donné $1 == name { - # Ici, nous avons accès à un certain nombre de variables utiles déjà préchargées : + # Ici, nous avons accès à un certain nombre de variables utiles déjà + # préchargées : # $0 est la ligne entière # $3 est le troisième champ. Ici il correspond à l'age qui nous intéresse # NF est le nombre de champs et vaut 3 # NR est le nombre d'enregistrements (lignes) vus jusqu'à présent # FILENAME est le nom du fichier en cours de traitement # FS est séparateur de champs, ici c'est " " (un espace) - # ...etc. Et beaucoup d'autre que vous pouvez connaître dans le manuel de man. - # Pour cela exécutez "man awk" dans votre terminal + # ...etc. Et beaucoup d'autre que vous pouvez connaître dans le manuel de + # man. Pour cela exécutez "man awk" dans votre terminal. # Garder une trace du total accumulé et du nombre de lignes correspondant. sum += $3; @@ -405,5 +412,6 @@ Pour plus d'informations : * [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 est dans la majorité des systèmes Linux. +* [The GNU Awk User's Guide](https://www.gnu.org/software/gawk/manual/gawk.html) + GNU Awk est dans la majorité des systèmes Linux. * [AWK one-liner collection](http://tuxgraphics.org/~guido/scripts/awk-one-liner.html) -- cgit v1.2.3 From 7a2f6ddacd5b5895bfc57baef19d17d24716061c Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 23 Nov 2022 22:01:08 +0100 Subject: keep introducing comments close to their object In previous commits, some introducing comments ended just in the line ahead of their example; others did not. For consistency, comments are now back to back with their example. --- fr-fr/awk-fr.html.markdown | 56 +++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/fr-fr/awk-fr.html.markdown b/fr-fr/awk-fr.html.markdown index 172a3ba4..a5db24b2 100644 --- a/fr-fr/awk-fr.html.markdown +++ b/fr-fr/awk-fr.html.markdown @@ -24,14 +24,12 @@ ce qui concerne le traitement de texte simple. Notamment le traitement de ceux qui nécessitent de lire des fichiers ligne par ligne ; chaque ligne comportant des champs séparés par des délimiteur. - ```awk #!/usr/bin/awk -f # Les commentaires commencent par un # - -# les programmes AWK consistent en une collection de règles et d'actions +# Les programmes AWK consistent en une collection de règles et d'actions. règle1 { action; } règle2 { action; } @@ -46,14 +44,14 @@ règle2 { action; } # texte. Si vous ne disposez pas de fichiers texte, considérez BEGIN comme le # point d’entrée principal du script. # À l'opposé de BEGIN, il existe la règle END. Cette règle est présente après -#chaque fin de fichier (EOF : End Of File). +# chaque fin de fichier (EOF : End Of File). BEGIN { # Les variables sont globales. Pas besoin de les déclarer. count = 0; - # les opérateurs sont identiques au langage C et aux langages similaires + # Les opérateurs sont identiques au langage C et aux langages similaires # (tels que C#, C++, etc.) a = count + 1; # addition b = count - 1; # soustraction @@ -122,7 +120,6 @@ BEGIN { arr[1] = "bar"; # Vous pouvez aussi initialiser un tableau avec la fonction split() - n = split("foo:bar:baz", arr, ":"); # Il y a aussi les tableaux associatifs @@ -131,7 +128,6 @@ BEGIN { # et les tableaux multi-dimensions, avec certaines limitations que l'on ne # mentionnera pas ici - multidim[0,0] = "foo"; multidim[0,1] = "bar"; multidim[1,0] = "baz"; @@ -150,19 +146,16 @@ BEGIN { for (argnum in ARGV) print ARGV[argnum]; - # Vous pouvez supprimer des éléments d'un tableau + # Vous pouvez supprimer des éléments d'un tableau. # C'est utile pour empêcher AWK de supposer que certains arguments soient # des fichiers à traiter. - delete ARGV[1]; # Le nombre d'arguments de la ligne de commande est assigné à # la variable ARGC print ARGC; - # AWK inclue trois catégories de fonction. - # On les examinera plus tard - + # AWK inclue trois catégories de fonction. On les examinera plus tard. return_value = arithmetic_functions(a, b, c); string_functions(); io_functions(); @@ -182,8 +175,8 @@ function arithmetic_functions(a, b, c, d) { # déclaration de fonction, comme ci-dessus. La convention veut que vous # mettiez quelques espaces supplémentaires pour faire la distinction entre # les paramètres réels et les variables locales. - # Dans cet exemple, a, b et c sont des paramètres réels, - # alors que d est simplement une variable locale. + # Dans cet exemple, a, b et c sont des paramètres réels, alors que d est + # simplement une variable locale. # Maintenant, les fonctions arithmétiques @@ -219,17 +212,16 @@ function string_functions( localvar, arr) { # AWK a plusieurs fonctions pour le traitement des chaînes de caractères, # dont beaucoup reposent sur des expressions régulières. - # Chercher et remplacer, la première occurrence (sub) ou toutes les - # occurrences (gsub) + # Chercher et remplacer, la première occurrence (sub), ou toutes les + # occurrences (gsub). # Les deux renvoient le nombre de correspondances remplacées - 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" # Rechercher une chaîne de caractères qui correspond à une expression # régulière index() fait la même chose, mais n'autorise pas les expressions - # régulières + # régulières. match(localvar, "t"); # => 4, puisque 't' est le quatrième caractère # Séparer par un délimiteur @@ -255,16 +247,13 @@ function io_functions( localvar) { # AWK n'a pas de descripteur de fichier en soi. Il ouvrira automatiquement # un descripteur de fichier lorsque vous utilisez quelque chose qui en a - # besoin. - # La chaîne de caractères que vous avez utilisée pour cela peut être traitée - # comme un descripteur de fichier à des fins d'entrée / sortie. - + # besoin. La chaîne de caractères que vous avez utilisée pour cela peut être + # traitée comme un descripteur de fichier à des fins d'entrée / sortie. outfile = "/tmp/foobar.txt"; - print "foobar" > outfile; # Maintenant, la chaîne de caractères "outfile" est un descripteur de - # fichier. Vous pouvez le fermer + # fichier. Vous pouvez le fermer. close(outfile); # Voici comment exécuter quelque chose dans le shell @@ -298,7 +287,7 @@ function io_functions( localvar) { # Cette action sera exécutée pour chaque ligne qui correspond à l'expression # régulière, /^fo+bar$/, et sera ignorée pour toute ligne qui n'y correspond - # pas. Imprimons simplement la ligne: + # pas. Imprimons simplement la ligne : print; @@ -311,11 +300,11 @@ function io_functions( localvar) { # exécutée, comme le fait le shell. Et, comme le shell, chaque champ est # accessible avec un signe dollar. - # Ceci affichera les deuxième et quatrième champs de la ligne. + # Ceci affichera les deuxième et quatrième champs de la ligne. print $2, $4; # AWK défini automatiquement beaucoup d'autres variables qui peuvent vous - # aider à inspecter et traiter chaque ligne. La plus importante est NF + # aider à inspecter et traiter chaque ligne. La plus importante est NF. # Affiche le nombre de champs de la ligne print NF; @@ -325,7 +314,6 @@ function io_functions( localvar) { } # Chaque règle est en réalité un test conditionnel. - a > 0 { # Ceci s’exécutera une fois pour chaque ligne, tant que le test est positif } @@ -333,19 +321,16 @@ a > 0 { # Les expressions régulières sont également des tests conditionnels. # Si le test de l'expression régulières n'est pas vrais alors le bloc # n'est pas exécuté. - $0 /^fobar/ { print "la ligne commence par foobar" } # Dans le cas où vous voulez tester votre chaîne de caractères sur la ligne # en cours de traitement $0 est optionnelle. - /^[a-zA-Z0-9]$/ { print "La ligne courante ne contient que des caractères alphanumériques."; } - # AWK peut parcourir un fichier texte ligne par ligne et exécuter des actions en # fonction de règles établies. Cela est si courant sous UNIX qu'AWK est un # langage de script. @@ -354,7 +339,7 @@ $0 /^fobar/ { # parfait. Le script lit un nom à partir de l'entrée standard, puis affiche # l'âge moyen de toutes les personnes portant ce prénom. # Supposons que vous fournissiez comme argument le nom d'un fichier comportant -# ces données: +# ces données : # # Bob Jones 32 # Jane Doe 22 @@ -397,9 +382,9 @@ $1 == name { # les fichiers texte. Contrairement à BEGIN, il ne fonctionne que si vous lui # donnez une entrée à traiter. Il sera exécuté une fois que tous les fichiers # auront été lus et traités conformément aux règles et aux actions que vous -# avez fournies. Le but est généralement de produire un rapport final -# ou de faire quelque chose avec l'ensemble des données que vous avez -# accumulées au cours du script. +# avez fournies. Le but est généralement de produire un rapport final, ou de +# faire quelque chose avec l'ensemble des données que vous avez accumulées +# au cours du script. END { @@ -408,6 +393,7 @@ END { } ``` + Pour plus d'informations : * [Awk tutorial](http://www.grymoire.com/Unix/Awk.html) -- cgit v1.2.3 From 11dbb27e750a0bf9f085226ae4520a9be03e1e1d Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 23 Nov 2022 22:08:19 +0100 Subject: account for markdownlint Account for two smaller suggestions put forward by markdownlint[1]. --- pt-br/awk-pt.html.markdown | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pt-br/awk-pt.html.markdown b/pt-br/awk-pt.html.markdown index 366ae886..597b0e7a 100644 --- a/pt-br/awk-pt.html.markdown +++ b/pt-br/awk-pt.html.markdown @@ -370,8 +370,10 @@ END { } ``` + Leituras adicionais (em inglês): * [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 é encontrado na maioria dos sistemas GNU/Linux. +* [The GNU Awk User's Guide](https://www.gnu.org/software/gawk/manual/gawk.html) + GNU AWK é encontrado na maioria dos sistemas GNU/Linux. -- cgit v1.2.3 From aae233d7fc62a226dac89ef0a1669c3d269c8134 Mon Sep 17 00:00:00 2001 From: Akshita Dixit <436_bt19@iiitkalyani.ac.in> Date: Sun, 27 Nov 2022 14:29:54 +0530 Subject: Add requested changes --- docker.html.markdown | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/docker.html.markdown b/docker.html.markdown index d65947fe..b1a20a72 100644 --- a/docker.html.markdown +++ b/docker.html.markdown @@ -123,7 +123,79 @@ $docker exec -it 7b272 bash # This command is used to run a command in the running container's default directory # Here 7b272 was our ubuntu container and the above command would help us interact with the container by opening a bash session -$docker compose +$docker logs +# Displays the information logged by the specified container +# root@7b27222e4bb7:/# whoami +# root +# root@7b27222e4bb7:/# pwd +# / +# root@7b27222e4bb7:/# ls +# bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var +# root@7b27222e4bb7:/# exit +# exit # More commands can be found at https://docs.docker.com/engine/reference/commandline/docker/ +``` +## The Dockerfile +The Dockerfile is a blueprint of a Docker image. We can mention the artifacts from our application along with their configurations into this file in the specific syntax to let anyone create a Docker image of our application. + +### A few things to keep in mind: +* It is always strictly named `Dockerfile` without any extensions +* We have to build our custom image on top of some already available Docker base image. (there is an empty image called `scratch` which literally lets you build an image from scratch) +* All capitalised commands are part of the syntax, they are not case-sensitive but used like a convention +* Below is a sample Dockerfile but you can read in depth from the [official docs](https://docs.docker.com/engine/reference/builder/). + +```Dockerfile +FROM +# define base image + +ENV USERNAME='admin'\ + PWD='****' +# optionally define environmental variables + +RUN apt-get update +# run linux commands inside container env, does not affect host env +# This executes during the time of image creation + +COPY +# executes on the host, copies files from src (usually on the host) to target on the container + +ENTRYPOINT ["some-script.sh"] +# executes an entire script as an entrypoint + +CMD [,...] +# always part of dockerfile, introduces entry point linux command e.g. `CMD node server.js` +# This executes after image creation only when the container from the image is running. +``` +### Build your images +Use the `docker build` command after wrapping your application into a Docker image to run ( or build) it. + +```bash + +$docker build +# used to build an image from the specified Dockerfile +# instead of path we could also specify a URL +# -t tag is optional and used to name and tag your images for e.g. `$docker build -t my-image:0.1 ./home/app` +# rebuild images everytime you make changes in the dockerfile +``` + +## Push your image to DockerHub +If you want your application's Docker image to be made publically available for any Docker user, you might wanna push it to the [Docker Hub](https://hub.docker.com/) which is a registry of Docker images. Make sure you have an account with a username and password on Docker Hub. + +When pushing an image to Docker Hub, we must specify our Docker Hub username as part of the source image name. We need to create the target image with the tag name of username/image-name much like GitHub repositories. + +```bash +$docker login +# to login to Docker Hub using your username and password + +$docker tag [:] [:] +# this tags a local src-image to a public target-image +# e.g. `docker tag my-sample-app:1.0.0 akshitadixit/my-sample-app` +# if tags are not specified, they're defaulted to `latest` + +$docker push [:] +# uploads our image to Docker Hub +# e.g. `docker push akshitadixit/my-sample-app` +# this image will be accessible under your profile's repositories as `https://hub.docker.com/r/username/image-name` + ``` \ No newline at end of file -- cgit v1.2.3 From 21ad76246245123f73057fa6a740703e9eba108f Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 30 Nov 2022 14:01:21 +0100 Subject: replace tabulator spaces by explicit spaces An instance of `sed -i "s/\t/ /g" CONTRIBUTING.markdown`. --- CONTRIBUTING.markdown | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown index 8d2a8320..bd4a8b25 100644 --- a/CONTRIBUTING.markdown +++ b/CONTRIBUTING.markdown @@ -35,7 +35,7 @@ review them more effectively and/or individually. in Vim) + You can check if the file contains a BOM on Linux/Unix systems by running `file language.html.markdown` You will see this if it uses a BOM: - `UTF-8 Unicode (with BOM) text`. + `UTF-8 Unicode (with BOM) text`. ### Header configuration @@ -87,19 +87,19 @@ You can build the site locally to test your changes. Follow the steps below. * Install Ruby language runtime and RubyGems. See [here](https://middlemanapp.com/basics/install/) for more details. * Clone or zip download the [learnxinyminutes-site](https://github.com/adambard/learnxinyminutes-site) repo. - * `git clone https://github.com/adambard/learnxinyminutes-site` + * `git clone https://github.com/adambard/learnxinyminutes-site` * Install Middleman and other required dependencies using Bundler. - * `cd learnxinyminutes-site/` - * `bundle install` + * `cd learnxinyminutes-site/` + * `bundle install` * Get the source in place - * Copy the contents of your clone of the fork of learnxinyminutes-docs repo - into the `source/docs` folder. There shouldn't be a `learnxinyminutes-docs` - folder inside the `docs` folder, it should just contain all the repo - contents. - * Checkout your fork of the learnxinyminutes-docs repo as `source/docs`. - * `cd source/docs/` - * `git clone https://github.com/YOUR-USERNAME/learnxinyminutes-docs ./source/docs/` + * Copy the contents of your clone of the fork of learnxinyminutes-docs repo + into the `source/docs` folder. There shouldn't be a `learnxinyminutes-docs` + folder inside the `docs` folder, it should just contain all the repo + contents. + * Checkout your fork of the learnxinyminutes-docs repo as `source/docs`. + * `cd source/docs/` + * `git clone https://github.com/YOUR-USERNAME/learnxinyminutes-docs ./source/docs/` * Build the site or run a development server to test your changes (NOTE: run these commands at `learnxinyminutes-site/`). - * Build - `bundle exec middleman build` - * Dev server - `bundle exec middleman --force-polling --verbose` + * Build - `bundle exec middleman build` + * Dev server - `bundle exec middleman --force-polling --verbose` -- cgit v1.2.3 From 140b6da5cd603c04f993ca37ecd645b509d084dc Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 30 Nov 2022 14:04:36 +0100 Subject: consistent mark-up first level bullet list An instance of `sed -i "s/^-/*/" CONTRIBUTING.markdown`. --- CONTRIBUTING.markdown | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown index bd4a8b25..97e7a821 100644 --- a/CONTRIBUTING.markdown +++ b/CONTRIBUTING.markdown @@ -16,19 +16,19 @@ review them more effectively and/or individually. ## Style Guidelines -- **Keep lines under 80 chars** +* **Keep lines under 80 chars** + Try to keep **line length in code blocks to 80 characters or fewer**. + Otherwise, the text will overflow and look odd. -- **Prefer example to exposition** +* **Prefer example to exposition** + Try to use as few words as possible. + Code examples are preferred over exposition in all cases. -- **Eschew surplusage** +* **Eschew surplusage** + We welcome newcomers, but the target audience for this site is programmers with some experience. + Try to avoid explaining basic concepts except for those specific to the language in question. + Keep articles succinct and scannable. We all know how to use Google here. -- **Use UTF-8** +* **Use UTF-8** + For translations (or EN articles with non-ASCII characters) please make sure your file is UTF-8 encoded. + Try to leave out the byte-order-mark at the start of the file. (`:set nobomb` @@ -47,31 +47,31 @@ some key information be defined in the header. The following fields are necessary for English articles about programming languages: -- **language** The *programming language* in question -- **contributors** A list of [author, URL] lists to credit +* **language** The *programming language* in question +* **contributors** A list of [author, URL] lists to credit Other fields: -- **category**: The category of the article. So far, can be one of *language*, +* **category**: The category of the article. So far, can be one of *language*, *tool* or *Algorithms & Data Structures*. Defaults to *language* if omitted. -- **filename**: The filename for this article's code. It will be fetched, mashed +* **filename**: The filename for this article's code. It will be fetched, mashed together, and made downloadable. + For non-English articles, *filename* should have a language-specific suffix. -- **lang**: For translations, the human language this article is in. For +* **lang**: For translations, the human language this article is in. For categorization, mostly. Here's an example header for an Esperanto translation of Ruby: ```yaml ---- +*-- language: ruby filename: learnruby-epo.ruby contributors: - ["Doktor Esperanto", "http://example.com/"] - ["Someone else", "http://someoneelseswebsite.com/"] lang: ep-ep ---- +*-- ``` ### Should I add myself as a Contributor? -- cgit v1.2.3 From fcc67f098b03074a0f3fd6502dfaecff59028cc7 Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 30 Nov 2022 14:07:56 +0100 Subject: use asterisk for second level bullet points Running `sed -i "s/^ +/ */" CONTRIBUTING.markdown`. This is to be complemented by a manual correction in the lower section, too. --- CONTRIBUTING.markdown | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown index 97e7a821..df0ef80a 100644 --- a/CONTRIBUTING.markdown +++ b/CONTRIBUTING.markdown @@ -17,23 +17,23 @@ review them more effectively and/or individually. ## Style Guidelines * **Keep lines under 80 chars** - + Try to keep **line length in code blocks to 80 characters or fewer**. - + Otherwise, the text will overflow and look odd. + * Try to keep **line length in code blocks to 80 characters or fewer**. + * Otherwise, the text will overflow and look odd. * **Prefer example to exposition** - + Try to use as few words as possible. - + Code examples are preferred over exposition in all cases. + * Try to use as few words as possible. + * Code examples are preferred over exposition in all cases. * **Eschew surplusage** - + We welcome newcomers, but the target audience for this site is programmers + * We welcome newcomers, but the target audience for this site is programmers with some experience. - + Try to avoid explaining basic concepts except for those specific to the + * Try to avoid explaining basic concepts except for those specific to the language in question. - + Keep articles succinct and scannable. We all know how to use Google here. + * Keep articles succinct and scannable. We all know how to use Google here. * **Use UTF-8** - + For translations (or EN articles with non-ASCII characters) please make sure + * For translations (or EN articles with non-ASCII characters) please make sure your file is UTF-8 encoded. - + Try to leave out the byte-order-mark at the start of the file. (`:set nobomb` + * Try to leave out the byte-order-mark at the start of the file. (`:set nobomb` in Vim) - + You can check if the file contains a BOM on Linux/Unix systems by running + * You can check if the file contains a BOM on Linux/Unix systems by running `file language.html.markdown` You will see this if it uses a BOM: `UTF-8 Unicode (with BOM) text`. -- cgit v1.2.3 From f33c10645494888c2f0d0c046bde20d1e0223462 Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 30 Nov 2022 14:15:44 +0100 Subject: manual adjustments, second level of indentation Manual adjustments and light edits to stay within the 80 character limit per line. Manual dedent of second level entries met in the lower part of the document. --- CONTRIBUTING.markdown | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown index df0ef80a..af97f92d 100644 --- a/CONTRIBUTING.markdown +++ b/CONTRIBUTING.markdown @@ -24,15 +24,15 @@ review them more effectively and/or individually. * Code examples are preferred over exposition in all cases. * **Eschew surplusage** * We welcome newcomers, but the target audience for this site is programmers - with some experience. + with some experience. * Try to avoid explaining basic concepts except for those specific to the - language in question. + language in question. * Keep articles succinct and scannable. We all know how to use Google here. * **Use UTF-8** - * For translations (or EN articles with non-ASCII characters) please make sure - your file is UTF-8 encoded. - * Try to leave out the byte-order-mark at the start of the file. (`:set nobomb` - in Vim) + * For translations (or EN articles with non-ASCII characters) please ensure + your file is UTF-8 encoded. + * Try to leave out the byte-order-mark at the start of the file (in Vim, use + `:set nobomb`). * You can check if the file contains a BOM on Linux/Unix systems by running `file language.html.markdown` You will see this if it uses a BOM: `UTF-8 Unicode (with BOM) text`. @@ -56,8 +56,8 @@ Other fields: *tool* or *Algorithms & Data Structures*. Defaults to *language* if omitted. * **filename**: The filename for this article's code. It will be fetched, mashed together, and made downloadable. - + For non-English articles, *filename* should have a language-specific - suffix. + * For non-English articles, *filename* should have a language-specific + suffix. * **lang**: For translations, the human language this article is in. For categorization, mostly. @@ -87,19 +87,19 @@ You can build the site locally to test your changes. Follow the steps below. * Install Ruby language runtime and RubyGems. See [here](https://middlemanapp.com/basics/install/) for more details. * Clone or zip download the [learnxinyminutes-site](https://github.com/adambard/learnxinyminutes-site) repo. - * `git clone https://github.com/adambard/learnxinyminutes-site` + * `git clone https://github.com/adambard/learnxinyminutes-site` * Install Middleman and other required dependencies using Bundler. - * `cd learnxinyminutes-site/` - * `bundle install` + * `cd learnxinyminutes-site/` + * `bundle install` * Get the source in place - * Copy the contents of your clone of the fork of learnxinyminutes-docs repo - into the `source/docs` folder. There shouldn't be a `learnxinyminutes-docs` - folder inside the `docs` folder, it should just contain all the repo - contents. - * Checkout your fork of the learnxinyminutes-docs repo as `source/docs`. + * Copy the contents of your clone of the fork of learnxinyminutes-docs repo + into the `source/docs` folder. There shouldn't be a `learnxinyminutes-docs` + folder inside the `docs` folder, it should just contain all the repo + contents. + * Checkout your fork of the learnxinyminutes-docs repo as `source/docs`. * `cd source/docs/` * `git clone https://github.com/YOUR-USERNAME/learnxinyminutes-docs ./source/docs/` * Build the site or run a development server to test your changes (NOTE: run these commands at `learnxinyminutes-site/`). - * Build - `bundle exec middleman build` - * Dev server - `bundle exec middleman --force-polling --verbose` + * Build - `bundle exec middleman build` + * Dev server - `bundle exec middleman --force-polling --verbose` -- cgit v1.2.3 From 7cf9a2b7aaab2829e7dcb28d082e4e4fab74336f Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 30 Nov 2022 14:18:56 +0100 Subject: adjust third level of indentation (manual) --- CONTRIBUTING.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown index af97f92d..a3d75101 100644 --- a/CONTRIBUTING.markdown +++ b/CONTRIBUTING.markdown @@ -97,8 +97,8 @@ You can build the site locally to test your changes. Follow the steps below. folder inside the `docs` folder, it should just contain all the repo contents. * Checkout your fork of the learnxinyminutes-docs repo as `source/docs`. - * `cd source/docs/` - * `git clone https://github.com/YOUR-USERNAME/learnxinyminutes-docs ./source/docs/` + * `cd source/docs/` + * `git clone https://github.com/YOUR-USERNAME/learnxinyminutes-docs ./source/docs/` * Build the site or run a development server to test your changes (NOTE: run these commands at `learnxinyminutes-site/`). * Build - `bundle exec middleman build` -- cgit v1.2.3 From eddf5accb885230940aa8d7c9a3375755d057e7b Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 30 Nov 2022 14:22:46 +0100 Subject: additional polish with markdownlint Accounts for most of the remaining suggestions by markdownlint.[1] [1] https://github.com/markdownlint/markdownlint, version 0.12.0. --- CONTRIBUTING.markdown | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown index a3d75101..3d2853c6 100644 --- a/CONTRIBUTING.markdown +++ b/CONTRIBUTING.markdown @@ -37,7 +37,6 @@ review them more effectively and/or individually. `file language.html.markdown` You will see this if it uses a BOM: `UTF-8 Unicode (with BOM) text`. - ### Header configuration The actual site uses Middleman to generate HTML files from these Markdown ones. @@ -56,7 +55,7 @@ Other fields: *tool* or *Algorithms & Data Structures*. Defaults to *language* if omitted. * **filename**: The filename for this article's code. It will be fetched, mashed together, and made downloadable. - * For non-English articles, *filename* should have a language-specific + * For non-English articles, *filename* should have a language-specific suffix. * **lang**: For translations, the human language this article is in. For categorization, mostly. @@ -85,8 +84,12 @@ addition or not. You can build the site locally to test your changes. Follow the steps below. -* Install Ruby language runtime and RubyGems. See [here](https://middlemanapp.com/basics/install/) for more details. -* Clone or zip download the [learnxinyminutes-site](https://github.com/adambard/learnxinyminutes-site) repo. +* Install Ruby language runtime and RubyGems. See + [here](https://middlemanapp.com/basics/install/) + for more details. +* Clone or zip download the + [learnxinyminutes-site](https://github.com/adambard/learnxinyminutes-site) + repository. * `git clone https://github.com/adambard/learnxinyminutes-site` * Install Middleman and other required dependencies using Bundler. * `cd learnxinyminutes-site/` @@ -100,6 +103,6 @@ You can build the site locally to test your changes. Follow the steps below. * `cd source/docs/` * `git clone https://github.com/YOUR-USERNAME/learnxinyminutes-docs ./source/docs/` * Build the site or run a development server to test your changes (NOTE: run -these commands at `learnxinyminutes-site/`). + these commands at `learnxinyminutes-site/`). * Build - `bundle exec middleman build` * Dev server - `bundle exec middleman --force-polling --verbose` -- cgit v1.2.3 From 23a2d02f7f3a5b8750c2061e60d16156fe843d15 Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Wed, 30 Nov 2022 14:28:20 +0100 Subject: add hint to markdownlint In the longer term, the use of a linter (similar to pylint for Python) may contribute to easier maintenance of the markdown files and consistent display of the content on the web page. --- CONTRIBUTING.markdown | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown index 3d2853c6..430ecea0 100644 --- a/CONTRIBUTING.markdown +++ b/CONTRIBUTING.markdown @@ -19,6 +19,9 @@ review them more effectively and/or individually. * **Keep lines under 80 chars** * Try to keep **line length in code blocks to 80 characters or fewer**. * Otherwise, the text will overflow and look odd. + * This and other potential pitfalls to format the content consistently are + identified by the freely available + [markdownlint](https://github.com/markdownlint/markdownlint). * **Prefer example to exposition** * Try to use as few words as possible. * Code examples are preferred over exposition in all cases. -- cgit v1.2.3 From 4d6309b2bde3c927691b15d049ef7a31c678e1f1 Mon Sep 17 00:00:00 2001 From: Marcel Ribeiro Dantas Date: Thu, 1 Dec 2022 19:29:50 -0300 Subject: Add missing json import --- python.html.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/python.html.markdown b/python.html.markdown index 2247f263..175f17ec 100644 --- a/python.html.markdown +++ b/python.html.markdown @@ -503,6 +503,7 @@ contents = {"aa": 12, "bb": 21} with open("myfile1.txt", "w+") as file: file.write(str(contents)) # writes a string to a file +import json with open("myfile2.txt", "w+") as file: file.write(json.dumps(contents)) # writes an object to a file -- cgit v1.2.3 From 354fe6fe7dd8085b88b0b1a2af2f5e612fe196f2 Mon Sep 17 00:00:00 2001 From: shoreyk <60650208+shoreyk@users.noreply.github.com> Date: Thu, 8 Dec 2022 11:19:58 +0800 Subject: [lua/zh-cn] loadstring -> load (#4554) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit loadstring已弃用 --- zh-cn/lua-cn.html.markdown | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zh-cn/lua-cn.html.markdown b/zh-cn/lua-cn.html.markdown index 6736dc2a..6fd10a32 100644 --- a/zh-cn/lua-cn.html.markdown +++ b/zh-cn/lua-cn.html.markdown @@ -391,7 +391,8 @@ dofile('mod2') --> Hi! (再次运行,与require不同) f = loadfile('mod2') -- Calling f() runs mod2.lua. -- loadstring是loadfile的字符串版本。 -g = loadstring('print(343)') --返回一个函数。 +-- (loadstring已弃用, 使用load代替) +g = load('print(343)') --返回一个函数。 g() -- 打印343; 在此之前什么也不打印。 --]] -- cgit v1.2.3 From bba9f7df211d63293e2a957872d156a0a6dfcd48 Mon Sep 17 00:00:00 2001 From: Marcel Ribeiro-Dantas Date: Sat, 10 Dec 2022 12:05:34 -0300 Subject: Fixes typos in many different English articles Signed-off-by: Marcel Ribeiro-Dantas --- ansible.html.markdown | 4 ++-- c.html.markdown | 2 +- citron.html.markdown | 4 ++-- directx9.html.markdown | 18 +++++++++--------- docker.html.markdown | 2 +- hdl.html.markdown | 4 ++-- hjson.html.markdown | 2 +- javascript.html.markdown | 2 +- jsonnet.html.markdown | 2 +- kdb+.html.markdown | 2 +- lambda-calculus.html.markdown | 2 +- lbstanza.html.markdown | 4 ++-- m.html.markdown | 2 +- markdown.html.markdown | 2 +- mercurial.html.markdown | 14 +++++++------- mips.html.markdown | 2 +- montilang.html.markdown | 2 +- opengl.html.markdown | 14 +++++++------- p5.html.markdown | 4 ++-- pascal.html.markdown | 2 +- php.html.markdown | 2 +- processing.html.markdown | 6 +++--- purescript.html.markdown | 4 ++-- raku-pod.html.markdown | 2 +- raku.html.markdown | 4 ++-- scala.html.markdown | 2 +- sing.html.markdown | 2 +- smalltalk.html.markdown | 2 +- tcsh.html.markdown | 2 +- textile.html.markdown | 6 +++--- tmux.html.markdown | 2 +- vala.html.markdown | 2 +- vim.html.markdown | 2 +- vimscript.html.markdown | 10 +++++----- vyper.html.markdown | 20 ++++++++++---------- yaml.html.markdown | 2 +- zig.html.markdown | 16 ++++++++-------- 37 files changed, 88 insertions(+), 88 deletions(-) diff --git a/ansible.html.markdown b/ansible.html.markdown index 839aed24..847505c1 100644 --- a/ansible.html.markdown +++ b/ansible.html.markdown @@ -44,7 +44,7 @@ for, which provides an excellent UI. #### Cons * It is an agent-less tool - every agent consumes up to 16MB ram - in some -environments, it may be noticable amount. +environments, it may be noticeable amount. * It is agent-less - you have to verify your environment consistency 'on-demand' - there is no built-in mechanism that would warn you about some change automatically (this can be achieved with reasonable effort) @@ -691,7 +691,7 @@ to specify the username. Note: You may like to execute Ansible with `--ask-sudo-pass` or add the user to sudoers file in order to allow non-supervised execution if you require 'admin' -privilages. +privileges. [Read more](http://docs.ansible.com/ansible/latest/become.html) diff --git a/c.html.markdown b/c.html.markdown index cd6b5ad2..ef341abf 100644 --- a/c.html.markdown +++ b/c.html.markdown @@ -256,7 +256,7 @@ int main (int argc, char** argv) // Floating-point numbers are defined by IEEE 754, thus cannot store perfectly // exact values. For instance, the following does not produce expected results - // because 0.1 might actually be 0.099999999999 insided the computer, and 0.3 + // because 0.1 might actually be 0.099999999999 inside the computer, and 0.3 // might be stored as 0.300000000001. (0.1 + 0.1 + 0.1) != 0.3; // => 1 (true) // and it is NOT associative due to reasons mentioned above. diff --git a/citron.html.markdown b/citron.html.markdown index bd3c398c..ce607ca1 100644 --- a/citron.html.markdown +++ b/citron.html.markdown @@ -68,7 +68,7 @@ False not. # True ########################################### # You may assign values to the current scope: -var name is value. # assignes `value` into `name` +var name is value. # assigns `value` into `name` # You may also assign values into the current object's namespace my name is value. # assigns `value` into the current object's `name` property @@ -146,7 +146,7 @@ add(3, 5). # 8 3 `add` 5. # 8 # This call binds as such: add[(3), 5] -# because the default fixity is left, and the default precedance is 1 +# because the default fixity is left, and the default precedence is 1 # You may change the precedence/fixity of this operator with a pragma #:declare infixr 1 add diff --git a/directx9.html.markdown b/directx9.html.markdown index b51f418d..586865c8 100644 --- a/directx9.html.markdown +++ b/directx9.html.markdown @@ -12,7 +12,7 @@ all began with Direct, such as Direct3D, DirectDraw, DirectMusic, DirectPlay, Di Direct3D (the 3D graphics API within DirectX) is widely used in the development of video games for Microsoft Windows and the Xbox line of consoles.[1] -In this tutorial we will be focusing on DirectX 9, which is not as low-level as it's sucessors, which are aimed at programmers very familiar with how graphics hardware works. It makes a great starting point for learning Direct3D. In this tutorial I will be using the Win32-API for window handling and the DirectX 2010 SDK. +In this tutorial we will be focusing on DirectX 9, which is not as low-level as it's successors, which are aimed at programmers very familiar with how graphics hardware works. It makes a great starting point for learning Direct3D. In this tutorial I will be using the Win32-API for window handling and the DirectX 2010 SDK. ## Window creation @@ -125,7 +125,7 @@ bool InitD3D(HWND hWnd) { pp.hDeviceWindow = hWnd; // associated window handle pp.Windowed = true; // display in window mode pp.Flags = 0; // no special flags - // Variable to store results of methods to check if everything succeded. + // Variable to store results of methods to check if everything succeeded. HRESULT result{ }; result = _d3d->CreateDevice(D3DADAPTER_DEFAULT, // use default graphics card D3DDEVTYPE_HAL, // use hardware acceleration @@ -144,7 +144,7 @@ bool InitD3D(HWND hWnd) { viewport.Y = 0; // .. viewport.Width = clientRect.right; // use the entire window viewport.Height = clientRect.bottom; // .. - viewport.MinZ = 0.0f; // minimun view distance + viewport.MinZ = 0.0f; // minimum view distance viewport.MaxZ = 100.0f; // maximum view distance // Apply the created viewport. result = _device->SetViewport(&viewport); @@ -157,7 +157,7 @@ bool InitD3D(HWND hWnd) { // ... // Back in our WinMain function we call our initialization function. // ... -// Check if Direct3D initialization succeded, else exit the application. +// Check if Direct3D initialization succeeded, else exit the application. if (!InitD3D(hWnd)) return -1; @@ -197,7 +197,7 @@ Let's create a vertex buffer to store the vertices for our triangle #include // First we declare a new ComPtr holding a vertex buffer. ComPtr _vertexBuffer{ }; -// Lets define a funtion to calculate the byte size of a std::vector +// Lets define a function to calculate the byte size of a std::vector template unsigned int GetByteSize(const std::vector& vec) { return sizeof(vec[0]) * vec.size(); @@ -253,7 +253,7 @@ if (!InitD3D(hWnd)) return -1; // Define the vertices we need to draw a triangle. // Values are declared in a clockwise direction else Direct3D would cull them. -// If you want to diable culling just call: +// If you want to disable culling just call: // _device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); std::vector vertices { // Bottom left @@ -274,7 +274,7 @@ if (!(_vertexBuffer = CreateBuffer(vertices))) Before we can use the vertex buffer to draw our primitives, we first need to set up the matrices. ```cpp -// Lets create a new funtions for the matrix transformations. +// Lets create a new functions for the matrix transformations. bool SetupTransform() { // Create a view matrix that transforms world space to // view space. @@ -338,7 +338,7 @@ if (FAILED(result)) // Create a world transformation matrix and set it to an identity matrix. D3DXMATRIX world{ }; D3DXMatrixIdentity(&world); -// Create a scalation matrix scaling our primitve by 10 in the x, +// Create a scalation matrix scaling our primitive by 10 in the x, // 10 in the y and keeping the z direction. D3DXMATRIX scaling{ }; D3DXMatrixScaling(&scaling, // matrix to scale @@ -499,7 +499,7 @@ std::vector vertexDeclDesc { 0, // byte offset from the struct beginning D3DDECLTYPE_FLOAT3, // data type (3d float vector) D3DDECLMETHOD_DEFAULT, // tessellator operation - D3DDECLUSAGE_POSTION, // usage of the data + D3DDECLUSAGE_POSITION, // usage of the data 0 }, // index (multiples usage of the same type) { 0, 12, // byte offset (3 * sizeof(float) bytes) diff --git a/docker.html.markdown b/docker.html.markdown index e18db5c9..0e61151e 100644 --- a/docker.html.markdown +++ b/docker.html.markdown @@ -254,7 +254,7 @@ $docker build ``` ## Push your image to DockerHub -If you want your application's Docker image to be made publically available for +If you want your application's Docker image to be made publicly available for any Docker user, you might wanna push it to the [Docker Hub](https://hub.docker.com/) which is a registry of Docker images. Make sure you have an account with a username and password on Docker Hub. diff --git a/hdl.html.markdown b/hdl.html.markdown index 3c3aff66..6b9a2d80 100644 --- a/hdl.html.markdown +++ b/hdl.html.markdown @@ -12,7 +12,7 @@ It is used by circuit designers to simulate circuits and logic prior to wiring a HDL allows circuit designers to simulate circuits at a high level without being connected to specific components. ## Basic building blocks & introduction to the language--- -This programming language is built by simulating hardware chips and wiring. Normal programming functions are replaced with specialized chips that are added to the current wiring desing. Every base chip must be written as it's own file and imported to be used in the current chip, though they may be reused as often as desired. +This programming language is built by simulating hardware chips and wiring. Normal programming functions are replaced with specialized chips that are added to the current wiring design. Every base chip must be written as it's own file and imported to be used in the current chip, though they may be reused as often as desired. ```verilog // Single line comments start with two forward slashes. @@ -79,7 +79,7 @@ foo(in=a[0..7], out=c); // C is now a 2 bit internal bus // Note that internally defined busses cannot be subbussed! -// To access these elements, output or input them seperately: +// To access these elements, output or input them separately: foo(in[0]=false, in[1..7]=a[0..6], out[0]=out1, out[1]=out2); // out1 and out2 can then be passed into other circuits within the design. diff --git a/hjson.html.markdown b/hjson.html.markdown index 2abeca1a..b9b35062 100644 --- a/hjson.html.markdown +++ b/hjson.html.markdown @@ -55,7 +55,7 @@ Let's take a look at examples to see the key syntax differences! Oh wait.. there is! It's called Hjson. ''' - # Backslashes are interpretted as an escape character ONLY in quoted strings + # Backslashes are interpreted as an escape character ONLY in quoted strings slash: This will not have a new line\n slash-quoted: "This will definitely have a new line\n" diff --git a/javascript.html.markdown b/javascript.html.markdown index b290b553..ec250e45 100644 --- a/javascript.html.markdown +++ b/javascript.html.markdown @@ -620,7 +620,7 @@ function isEven(number) { }; // I put the word "equivalent" in double quotes because a function defined -// using the lambda syntax cannnot be called before the definition. +// using the lambda syntax cannot be called before the definition. // The following is an example of invalid usage: add(1, 8); diff --git a/jsonnet.html.markdown b/jsonnet.html.markdown index 241caf5f..f077c35b 100644 --- a/jsonnet.html.markdown +++ b/jsonnet.html.markdown @@ -131,7 +131,7 @@ assert obj5 == {}; ``` ## Further Reading -There are a few but important concepts that are not touched in this exmaple, including: +There are a few but important concepts that are not touched in this example, including: - Passing variables from command line: [Parameterize Entire Config](https://jsonnet.org/learning/tutorial.html#parameterize-entire-config) - Import other jsonnet libraries/files: [Imports](https://jsonnet.org/learning/tutorial.html#imports) diff --git a/kdb+.html.markdown b/kdb+.html.markdown index 680c01c1..db842726 100644 --- a/kdb+.html.markdown +++ b/kdb+.html.markdown @@ -560,7 +560,7 @@ select avg height by sex from t / => f | 160 / => m | 177.5 -/ If no aggreation function is specified, last is assumed +/ If no aggregation function is specified, last is assumed select by sex from t / => sex| name age height / => ---| ----------------- diff --git a/lambda-calculus.html.markdown b/lambda-calculus.html.markdown index 958dd746..775907c2 100644 --- a/lambda-calculus.html.markdown +++ b/lambda-calculus.html.markdown @@ -41,7 +41,7 @@ Evaluation is done via which is essentially lexically-scoped substitution. When evaluating the -expression `(λx.x)a`, we replace all occurences of "x" in the function's body +expression `(λx.x)a`, we replace all occurrences of "x" in the function's body with "a". - `(λx.x)a` evaluates to: `a` diff --git a/lbstanza.html.markdown b/lbstanza.html.markdown index 19dc7db7..06a38aef 100644 --- a/lbstanza.html.markdown +++ b/lbstanza.html.markdown @@ -193,7 +193,7 @@ while condition[0]: for i in 0 to 10 do: vector[i] = i -; stanza also supports named labels which can functin as break or return +; stanza also supports named labels which can function as break or return ; statements defn another-fn (): label return: @@ -218,7 +218,7 @@ for (x in xs, y in ys, z in zs) do : println("x:%_, y:%_, z:%_" % [x, y, z]) -;xs, ys, and zs are all "Seqable" meaing they are Seq types (sequences). +;xs, ys, and zs are all "Seqable" meaning they are Seq types (sequences). ; the `do` identifier is a special function that just applies the body of ; the for loop to each element of the sequence. ; diff --git a/m.html.markdown b/m.html.markdown index 96828ae5..87e0875e 100644 --- a/m.html.markdown +++ b/m.html.markdown @@ -198,7 +198,7 @@ M has an execution stack. When all levels of the stack have returned, the progra With an argument: execute a block of code & add a level to the stack. ``` -d ^routine ;run a routine from the begining. +d ^routine ;run a routine from the beginning. ; ;routines are identified by a caret. d tag ;run a tag in the current routine d tag^routine ;run a tag in different routine diff --git a/markdown.html.markdown b/markdown.html.markdown index cfc0ddf3..fefb60f6 100644 --- a/markdown.html.markdown +++ b/markdown.html.markdown @@ -298,7 +298,7 @@ omitted though.) - [Subchapter

](#subchapter-h3-) ``` -Nontheless, this is a feature that might not be working in all Markdown +Nonetheless, this is a feature that might not be working in all Markdown implementations the same way. ## Images diff --git a/mercurial.html.markdown b/mercurial.html.markdown index 98658f83..2c06ca77 100644 --- a/mercurial.html.markdown +++ b/mercurial.html.markdown @@ -22,13 +22,13 @@ and/or directorie(s) over time. * Distributed Architecture - Traditionally version control systems such as CVS and Subversion are a client server architecture with a central server to -store the revsion history of a project. Mercurial however is a truly -distributed architecture, giving each devloper a full local copy of the +store the revision history of a project. Mercurial however is a truly +distributed architecture, giving each developer a full local copy of the entire development history. It works independently of a central server. * Fast - Traditionally version control systems such as CVS and Subversion are a -client server architecture with a central server to store the revsion history +client server architecture with a central server to store the revision history of a project. Mercurial however is a truly distributed architecture, giving -each devloper a full local copy of the entire development history. It works +each developer a full local copy of the entire development history. It works independently of a central server. * Platform Independent - Mercurial was written to be highly platform independent. Much of Mercurial is written in Python, with small performance @@ -56,7 +56,7 @@ any later version. | changeset | Set of changes saved as diffs | | diff | Changes between file(s) | | tag | A named named revision | -| parent(s) | Immediate ancestor(s) of a revison | +| parent(s) | Immediate ancestor(s) of a revision | | branch | A child of a revision | | head | A head is a changeset with no child changesets | | merge | The process of merging two HEADS | @@ -184,7 +184,7 @@ Commit changes to the given files into the repository. # Commit with a message $ hg commit -m 'This is a commit message' -# Commit all added / removed files in the currrent tree +# Commit all added / removed files in the current tree $ hg commit -A 'Adding and removing all existing files in the tree' # amend the parent of the working directory with a new commit that contains the @@ -341,7 +341,7 @@ $ hg revert -a Remove the specified files on the next commit. ```bash -# Remove a spcific file +# Remove a specific file $ hg remove go_away.txt # Remove a group of files by pattern diff --git a/mips.html.markdown b/mips.html.markdown index 0e7a7d0c..31f735b0 100644 --- a/mips.html.markdown +++ b/mips.html.markdown @@ -111,7 +111,7 @@ gateways and routers. sub $t2, $t0, $t1 # $t2 = $t0 - $t1 mul $t2, $t0, $t1 # $t2 = $t0 * $t1 div $t2, $t0, $t1 # $t2 = $t0 / $t1 (Might not be - # supported in some versons of MARS) + # supported in some versions of MARS) div $t0, $t1 # Performs $t0 / $t1. Get the # quotient using 'mflo' and # remainder using 'mfhi' diff --git a/montilang.html.markdown b/montilang.html.markdown index cceb7aa1..483dc5a5 100644 --- a/montilang.html.markdown +++ b/montilang.html.markdown @@ -170,7 +170,7 @@ printseven /# 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. #/ +/# must have & on either side with no spaces, 'DEFINE' is case sensitive. #/ /# 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' #/ diff --git a/opengl.html.markdown b/opengl.html.markdown index 83ace3e8..993402f7 100644 --- a/opengl.html.markdown +++ b/opengl.html.markdown @@ -35,7 +35,7 @@ int main() { context }; window.setVerticalSyncEnabled(true); window.setActive(true); - // After that we initialise GLEW and check if an error occured. + // After that we initialise GLEW and check if an error occurred. GLenum error; glewExperimental = GL_TRUE; if ((err = glewInit()) != GLEW_OK) @@ -140,7 +140,7 @@ if (logSize > 0) { } ``` -The same is possibile after glLinkProgram(), just replace glGetShaderiv() with glGetProgramiv() +The same is possible after glLinkProgram(), just replace glGetShaderiv() with glGetProgramiv() and glGetShaderInfoLog() with glGetProgramInfoLog(). ```cpp @@ -194,7 +194,7 @@ void main() { out vec4 outColor; void main() { - // We simply set the ouput color to red. + // We simply set the output color to red. // The parameters are red, green, blue and alpha. outColor = vec4(1.0, 0.0, 0.0, 1.0); } @@ -233,7 +233,7 @@ glBufferData(GL_ARRAY_BUFFER, // target buffer // After filling the VBO link it to the location 0 in our vertex shader, // which holds the vertex position. // ... -// To ask for the attibute location, if you haven't set it: +// To ask for the attribute location, if you haven't set it: GLint posLocation = glGetAttribLocation(program, "position"); // .. glEnableVertexAttribArray(0); @@ -463,7 +463,7 @@ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(iboData[0]) * iboData.size(), iboData.data(), GL_STATIC_DRAW); // Next in our render loop, we replace glDrawArrays() with: -glDrawElements(GL_TRIANGLES, iboData.size(), GL_UNSINGED_INT, nullptr); +glDrawElements(GL_TRIANGLES, iboData.size(), GL_UNSIGNED_INT, nullptr); // Remember to delete the allocated memory for the IBO. ``` @@ -535,7 +535,7 @@ glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, nullptr); // ... glBindVertexArray(vao); glBindTexture(GL_TEXTURE_2D, texture); -glDrawElements(GL_TRIANGLES, iboData.size(), GL_UNSINGED_INT, nullptr); +glDrawElements(GL_TRIANGLES, iboData.size(), GL_UNSIGNED_INT, nullptr); // ... ``` @@ -673,7 +673,7 @@ glUniformMatrix4fv(modelLocation, 1, GL_FALSE, ## Geometry Shader -Gemoetry shaders were introduced in OpenGL 3.2, they can produce vertices +Geometry shaders were introduced in OpenGL 3.2, they can produce vertices that are send to the rasterizer. They can also change the primitive type e.g. they can take a point as an input and output other primitives. Geometry shaders are inbetween the vertex and the fragment shader. diff --git a/p5.html.markdown b/p5.html.markdown index f6084b98..d36d417f 100644 --- a/p5.html.markdown +++ b/p5.html.markdown @@ -29,11 +29,11 @@ function setup() { } function draw() { - ellipse(10, 10, 50, 50); // creates a ellipse at the 10px from the left and 10px from the top with width adn height as 50 each, so its basically a circle. + ellipse(10, 10, 50, 50); // creates a ellipse at the 10px from the left and 10px from the top with width and height as 50 each, so its basically a circle. //remember in p5.js the origin is at the top-left corner of the canvas if (mouseIsPressed) { - // mouseIsPressed is a boolean variable that changes to true if the mouse buttton is pressed down at that instant + // mouseIsPressed is a boolean variable that changes to true if the mouse button is pressed down at that instant fill(0); // fill refers to the innner color or filling color of whatever shape you are going to draw next } else { diff --git a/pascal.html.markdown b/pascal.html.markdown index 9c73c456..fe00791a 100644 --- a/pascal.html.markdown +++ b/pascal.html.markdown @@ -131,7 +131,7 @@ Begin str := 'apple'; bool := true; //pascal is not a case-sensitive language - //arithmethic operation + //arithmetic operation int := 1 + 1; // int = 2 overwriting the previous assignment int := int + 1; // int = 2 + 1 = 3; int := 4 div 2; //int = 2 division operation where result will be floored diff --git a/php.html.markdown b/php.html.markdown index 821bde8f..61f1c00c 100644 --- a/php.html.markdown +++ b/php.html.markdown @@ -443,7 +443,7 @@ $bar('C'); // Prints "A - B - C" // You can call named functions using strings $function_name = 'add'; echo $function_name(1, 2); // => 3 -// Useful for programatically determining which function to run. +// Useful for programmatically determining which function to run. // Or, use call_user_func(callable $callback [, $parameter [, ... ]]); diff --git a/processing.html.markdown b/processing.html.markdown index 777c6981..63f10e88 100644 --- a/processing.html.markdown +++ b/processing.html.markdown @@ -2,7 +2,7 @@ language: processing filename: learnprocessing.pde contributors: - - ["Phone Thant Ko", "http://github.com/phonethantko"] + - ["Phone Than Ko", "http://github.com/phonethantko"] - ["Divay Prakash", "https://github.com/divayprakash"] --- @@ -256,7 +256,7 @@ line(x1, y1, z1, x2, y2, z2); // In 3D space // Triangle triangle(x1, y1, x2, y2, x3, y3); -// Draws a triangle connecting three points defined by coordinate paramters. +// Draws a triangle connecting three points defined by coordinate parameters. // Rectangle rect(a, b, c, d, [r]); // With optional parameter defining the radius of all corners @@ -375,7 +375,7 @@ texture(image); // PImage can be passed into arguments for texture-mapping the s 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, +short documentation, so I will leave them out here. Should you be interested, please check out the references. ``` diff --git a/purescript.html.markdown b/purescript.html.markdown index 8cf1c1dd..1ceaecf9 100644 --- a/purescript.html.markdown +++ b/purescript.html.markdown @@ -59,9 +59,9 @@ compare 3 2 -- GT true && (9 >= 19 || 1 < 2) -- true -- Strings -"Hellow" :: String -- "Hellow" +"Hello" :: String -- "Hello" -- Multiline string without newlines, to run in PSCi use "paste" mode. -"Hellow\ +"Hello\ \orld" -- "Helloworld" -- Multiline string with newlines """Hello diff --git a/raku-pod.html.markdown b/raku-pod.html.markdown index 7e9b6fc3..b008beab 100644 --- a/raku-pod.html.markdown +++ b/raku-pod.html.markdown @@ -193,7 +193,7 @@ are C, C and C. ### Comments Although Pod blocks are ignored by the Rakudo Raku compiler, everything -indentified as a Pod block will be read and interpreted by Pod renderers. In +identified as a Pod block will be read and interpreted by Pod renderers. In order to prevent Pod blocks from being rendered by any renderer, use the `=comment` directive. diff --git a/raku.html.markdown b/raku.html.markdown index a8059791..53404f58 100644 --- a/raku.html.markdown +++ b/raku.html.markdown @@ -688,7 +688,7 @@ say (0 or False); # OUTPUT: «False␤». my ($a, $b, $c, $d, $e) = 1, 0, False, True, 'pi'; say $a && $b && $c; # OUTPUT: «0␤», the first falsey value say $a && $b && $c; # OUTPUT: «False␤», the first falsey value -say $a && $d && $e; # OUTPUT: «pi␤», last operand since everthing before is truthy +say $a && $d && $e; # OUTPUT: «pi␤», last operand since everything before is truthy # `||` returns the first argument that evaluates to `True`. say $b || $a || $d; # OUTPUT: «1␤» @@ -1965,7 +1965,7 @@ say so 'abbbbc' ~~ / a b* c /; # OUTPUT: «True␤» say so 'aec' ~~ / a b* c /; # OUTPUT: «False␤», "b"(s) are optional, not replaceable. # `**` - (Unbound) Quantifier -# If you squint hard enough, you might understand why exponentation is used +# If you squint hard enough, you might understand why exponentiation is used # for quantity. say so 'abc' ~~ / a b**1 c /; # OUTPUT: «True␤», exactly one time say so 'abc' ~~ / a b**1..3 c /; # OUTPUT: «True␤», one to three times diff --git a/scala.html.markdown b/scala.html.markdown index d2d45dc9..bb20f624 100644 --- a/scala.html.markdown +++ b/scala.html.markdown @@ -302,7 +302,7 @@ do { // Recursion is the idiomatic way of repeating an action in Scala (as in most // other functional languages). // Recursive functions need an explicit return type, the compiler can't infer it. -// Here it's Unit, which is analagous to a `void` return type in Java +// Here it's Unit, which is analogous to a `void` return type in Java def showNumbersInRange(a: Int, b: Int): Unit = { print(a) if (a < b) diff --git a/sing.html.markdown b/sing.html.markdown index 2e439800..50b52390 100644 --- a/sing.html.markdown +++ b/sing.html.markdown @@ -154,7 +154,7 @@ fn learnTypes() void sys.validate(dyna_array.size() == 1); // a map that associates a number to a string. - // "map(x)..." reads "map with key of type x and vaue of type..." + // "map(x)..." reads "map with key of type x and value of type..." var a_map map(string)i32; a_map.insert("one", 1); diff --git a/smalltalk.html.markdown b/smalltalk.html.markdown index aaa592dc..d4016ecf 100644 --- a/smalltalk.html.markdown +++ b/smalltalk.html.markdown @@ -60,7 +60,7 @@ doSomethingWith: argumentObject Everything here except the `^` involves sending more messages. Event the `ifTrue:` that you might think is a language control structure is just Smalltalk code. -We start by sending `size` to `self`. `self` is the object currently running the code - so in this case it is the myObject we started with. `size` is a very common message that we might anticipate tells us something about how big an object is; you could look it up with the Smalltalk tools very simply. The result we get is then sent the message `>` with the plain old integer 4 (which is an object too; no strange primitive types to pollute the system here) and nobody should be surprised the `>` is a comparison that answers true or false. That boolean (which is actually a Boolean object in Smalltalk) is sent the message `ifTrue:` with the block of code between the `[]` as its argument; obvioulsy a true boolean might be expected to run that block of code and a false to ignore it. +We start by sending `size` to `self`. `self` is the object currently running the code - so in this case it is the myObject we started with. `size` is a very common message that we might anticipate tells us something about how big an object is; you could look it up with the Smalltalk tools very simply. The result we get is then sent the message `>` with the plain old integer 4 (which is an object too; no strange primitive types to pollute the system here) and nobody should be surprised the `>` is a comparison that answers true or false. That boolean (which is actually a Boolean object in Smalltalk) is sent the message `ifTrue:` with the block of code between the `[]` as its argument; obviously a true boolean might be expected to run that block of code and a false to ignore it. If the block is run then we do some more message sending to the argument object and noting the `^` we return the answer back to our starting point and it gets assigned to `result`. If the block is ignored we seem to run out of code and so `self` is returned and assigned to `result`. diff --git a/tcsh.html.markdown b/tcsh.html.markdown index e38b7a27..05954442 100644 --- a/tcsh.html.markdown +++ b/tcsh.html.markdown @@ -713,7 +713,7 @@ end #### About [T]CSH: # * CSH is notorious about its bugs; # * It was also famous about its advanced interactive mode. -# * TCSH is famous that have the most advanced completition subsystem. +# * TCSH is famous that have the most advanced completion subsystem. # * TCSH is famous that have the most advanced aliases subsystem; aliases # can take parameters and often used as functions! # * TCSH is well known that preferred by people (me too) because of better diff --git a/textile.html.markdown b/textile.html.markdown index 2b81674a..293e647d 100644 --- a/textile.html.markdown +++ b/textile.html.markdown @@ -165,11 +165,11 @@ but again, they use different HTML markup and thus the distinction. ###. Superscripts and Subscripts use carats and tildes: -Superscripts are 2 ^nd^ to none, but subscripts are CO ~2~ L too. +Superscripts are 2 ^and^ to none, but subscripts are CO ~2~ L too. Note the spaces around the superscripts and subscripts. To avoid the spaces, add square brackets around them: -2[^nd^] and CO[~2~]L +2[^and^] and CO[~2~]L ###. Insertions and deletions are indicated using -/+ symbols: This is -deleted- text and this is +inserted+ text. @@ -375,7 +375,7 @@ table(tableclass). |a|classy|table| |a|classy|table| -###. Spanning rows and colums: +###. Spanning rows and columns: A backslash \ is used for a column span: |\2. spans two cols | diff --git a/tmux.html.markdown b/tmux.html.markdown index 1c2c2da3..095e24fb 100644 --- a/tmux.html.markdown +++ b/tmux.html.markdown @@ -183,7 +183,7 @@ bind a send-prefix ### Theme ########################################################################### -# Statusbar Color Palatte +# Statusbar Color Palette set-option -g status-justify left set-option -g status-bg black set-option -g status-fg white diff --git a/vala.html.markdown b/vala.html.markdown index 06d6dedc..739e0fda 100755 --- a/vala.html.markdown +++ b/vala.html.markdown @@ -486,7 +486,7 @@ int more = 57; int* more_pointer = &more; // & = address-of int indirection_demo = more_pointer*; // indirection -// Profiles: affect which Vala features are avaliable and which libraries the +// Profiles: affect which Vala features are available and which libraries the // C-code will use. // - gobject (default) // posix diff --git a/vim.html.markdown b/vim.html.markdown index e0fdf2e0..fb2fc81f 100644 --- a/vim.html.markdown +++ b/vim.html.markdown @@ -27,7 +27,7 @@ specific points in the file, and for fast editing. :wq # Save file and quit vim ZZ # Save file and quit vim :q! # Quit vim without saving file - # ! *forces* :q to execute, hence quiting vim without saving + # ! *forces* :q to execute, hence quitting vim without saving ZQ # Quit vim without saving file :x # Save file(only when the file is modified) and quit vim diff --git a/vimscript.html.markdown b/vimscript.html.markdown index 283e50c6..04fee6fa 100644 --- a/vimscript.html.markdown +++ b/vimscript.html.markdown @@ -38,7 +38,7 @@ echo 'Hello' | echo 'world!' " Putting a comment after a command usually works pwd " Displays the current working directory -" Except for some commands it does not; use the command delemiter before the +" Except for some commands it does not; use the command delimiter before the " comment (echo assumes that the quotation mark begins a string) echo 'Hello world!' | " Displays a message @@ -98,7 +98,7 @@ echo v:false | " Evaluates to 0 or the string 'v:false' " Boolean values can result from comparison of two objects. echo x == y | " Equality by value -echo x != y | " Unequality +echo x != y | " Inequality echo x > y | " Greater than echo x >= y | " Greater than or equal echo x < y | " Smaller than @@ -110,7 +110,7 @@ echo x isnot y | " Instance non-identity (lists and dictionaries) " echo 'a' < 'b'. Case sensitivity depends on the setting of 'ignorecase' " " Explicit case-sensitivity is specified by appending '#' (match case) or '?' -" (ignore case) to the operator. Prefer explicity case sensitivity when writing +" (ignore case) to the operator. Prefer explicitly case sensitivity when writing " portable scripts. echo 'a' < 'B' | " True or false depending on 'ignorecase' @@ -315,7 +315,7 @@ let s:isNumber = {x -> type(x) == type(0)} | " Local: any name allowed " Assign values of list to multiple variables (number of items must match) let [x, y] = [1, 2] -" Assign the remainer to a rest variable (note the semicolon) +" Assign the remainder to a rest variable (note the semicolon) let [mother, father; children] = ['Alice', 'Bob', 'Carol', 'Dennis', 'Emily'] @@ -610,7 +610,7 @@ echo exists(':Make') | " Command echo exists("#CursorHold") | " Auto-command defined for event echo exists("#BufReadPre#*.gz") | " Event and pattern echo exists("#filetypeindent") | " Auto-command group -echo exists("##ColorScheme") | " Auto-commnand supported for event +echo exists("##ColorScheme") | " Auto-command supported for event " Various dynamic values (see |expand()|) echo expand('%') | " Current file name diff --git a/vyper.html.markdown b/vyper.html.markdown index fec1a79f..bad0c31e 100644 --- a/vyper.html.markdown +++ b/vyper.html.markdown @@ -181,7 +181,7 @@ def _changeTaskStatus( \ _status: uint256, \ ): # backslashes (\) allow for multi-line code - # Natspec comments are particularly helpful for documentation and readibility + # Natspec comments are particularly helpful for documentation and readability # Natspec can be included using familiar Pythonic docstring syntax """ @notice @@ -429,16 +429,16 @@ struct Struct: owner: address _balance: uint256 # balance is a reserved keyword, is a member for addresses -exampleStuct: Struct +exampleStruct: Struct @public def foo() -> uint256: - self.exampleStuct = Struct({owner: msg.sender, _balance: 5}) - self.exampleStuct._balance = 10 - self.exampleStuct._balance = 5 # set to new value - clear(self.exampleStuct._balance) - clear(self.exampleStuct) - return self.exampleStuct._balance + self.exampleStruct = Struct({owner: msg.sender, _balance: 5}) + self.exampleStruct._balance = 10 + self.exampleStruct._balance = 5 # set to new value + clear(self.exampleStruct._balance) + clear(self.exampleStruct) + return self.exampleStruct._balance # Data locations: Memory vs. storage vs. calldata - all complex types (arrays, @@ -510,7 +510,7 @@ def increment(x: uint256, y: uint256) -> (uint256, uint256): y += 1 return (x, y) -# Call previous functon +# Call previous function @public @constant def willCall() -> (uint256, uint256): @@ -679,7 +679,7 @@ sha3(concat("ab", "cd")) # returns bytes32 # Step 1. Commit # Place a commitment by sending output of `sha3()` -sha3("a secret"); # btyes32 commit +sha3("a secret"); # bytes32 commit sha3(concat("secret", "other secret", "salt")); # commit multiple things # The `sha3()` calculation should occur off-chain, only the bytes32 # output should be inputted into some `commit()` function diff --git a/yaml.html.markdown b/yaml.html.markdown index 3b40e6a7..ce64906f 100644 --- a/yaml.html.markdown +++ b/yaml.html.markdown @@ -204,7 +204,7 @@ python_complex_number: !!python/complex 1+2j # Strings and numbers aren't the only scalars that YAML can understand. # ISO-formatted date and datetime literals are also parsed. datetime_canonical: 2001-12-15T02:59:43.1Z -datetime_space_seperated_with_time_zone: 2001-12-14 21:59:43.10 -5 +datetime_space_separated_with_time_zone: 2001-12-14 21:59:43.10 -5 date_implicit: 2002-12-14 date_explicit: !!timestamp 2002-12-14 diff --git a/zig.html.markdown b/zig.html.markdown index 0efe5f64..82c6b994 100644 --- a/zig.html.markdown +++ b/zig.html.markdown @@ -69,7 +69,7 @@ pub fn main() void { ### Booleans, integers and float. ```zig // Booleans. -// Keywords are prefered to operators for boolean operations. +// Keywords are preferred to operators for boolean operations. print("{}\n{}\n{}\n", .{ true and false, true or false, @@ -138,7 +138,7 @@ var some_integers: [10]i32 = undefined; some_integers[0] = 30; // first element of the array is now 30 -var x = some_integers[0]; // "x" now equals to 30, its type is infered. +var x = some_integers[0]; // "x" now equals to 30, its type is inferred. var y = some_integers[1]; // Second element of the array isn't defined. // "y" got a stack garbage value (no runtime error). @@ -707,8 +707,8 @@ However, here are some examples, to get an idea of what you can expect: Use a fixed buffer to get its memory, don't ask memory to the kernel. Very simple, limited and wasteful (can't deallocate), but very fast. - ArenaAllocator. - Allow to free all allocted memory at once. - To use in combinaison with another allocator. + Allow to free all allocated memory at once. + To use in combinations with another allocator. Very simple way of avoiding leaks. A first example. @@ -825,7 +825,7 @@ fn arena_allocator_fn() !void { // Combining the general purpose and arena allocators. Both are very useful, -// and their combinaison should be in everyone's favorite cookbook. +// and their combinations should be in everyone's favorite cookbook. fn gpa_arena_allocator_fn() !void { const config = .{.safety = true}; var gpa = std.heap.GeneralPurposeAllocator(config){}; @@ -925,7 +925,7 @@ test "returns true" { The compiler has special functions called "built-ins", starting with an "@". There are more than a hundred built-ins, allowing very low-level stuff: - compile-time errors, logging, verifications -- type coercion and convertion, even in an unsafe way +- type coercion and conversion, even in an unsafe way - alignment management - memory tricks (such as getting the byte offset of a field in a struct) - calling functions at compile-time @@ -956,7 +956,7 @@ if (@enumToInt(Value.blah) == 2) { ... } Unions cannot be reinterpreted (in an union with an integer and a float, one cannot take a value for another by accident). Etc. - Removing most of the C undefined behaviors (UBs), and when the compiler encounters one, it stops. -- Slice and Array structures are prefered to pointers. +- Slice and Array structures are preferred to pointers. Types enforced by the compiler are less prone to errors than pointer manipulations. - Numerical overflows produce an error, unless explicitly accepted using wrapping operators. - Try and catch mechanism. @@ -964,7 +964,7 @@ if (@enumToInt(Value.blah) == 2) { ... } - Unused variables are considered as errors by the compiler. - Many pointer types exist in order to represent what is pointed. Example: is this a single value or an array, is the length known, etc. -- Structures need a value for their attributes, and it still is possible to give an undefined value (stack garbage), but at least it is explicitely undefined. +- Structures need a value for their attributes, and it still is possible to give an undefined value (stack garbage), but at least it is explicitly undefined. ## Further Reading -- cgit v1.2.3 From fd802bfd4380c90530c084267a23b8fd1344f374 Mon Sep 17 00:00:00 2001 From: zjzj1996 Date: Wed, 11 Jan 2023 15:10:03 +0800 Subject: fix:typo --- cs-cz/go.html.markdown | 2 +- fi-fi/go-fi.html.markdown | 2 +- fr-fr/go-fr.html.markdown | 2 +- go.html.markdown | 2 +- it-it/go-it.html.markdown | 2 +- pt-br/go-pt.html.markdown | 2 +- ru-ru/go-ru.html.markdown | 2 +- zh-cn/go-cn.html.markdown | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cs-cz/go.html.markdown b/cs-cz/go.html.markdown index 36217414..cef8c5ab 100644 --- a/cs-cz/go.html.markdown +++ b/cs-cz/go.html.markdown @@ -33,7 +33,7 @@ Go má již v základu vynikající knihovnu a je s ním spojená nadšená komu řádkový komentář */ // Každý zdroják začíná deklarací balíčku (package) -// Main je vyhrazené jméno, které označuje spustitelný soubor, +// main je vyhrazené jméno, které označuje spustitelný soubor, // narozdíl od knihovny package main diff --git a/fi-fi/go-fi.html.markdown b/fi-fi/go-fi.html.markdown index af304099..15acdbae 100644 --- a/fi-fi/go-fi.html.markdown +++ b/fi-fi/go-fi.html.markdown @@ -33,7 +33,7 @@ Go tuo mukanaan loistavan oletuskirjaston sekä innokkaan yhteisön. rivin kommentti */ // Package -lausekkeella aloitetaan jokainen lähdekooditiedosto. -// Main on erityinen nimi joka ilmoittaa +// main on erityinen nimi joka ilmoittaa // suoritettavan tiedoston kirjaston sijasta. package main diff --git a/fr-fr/go-fr.html.markdown b/fr-fr/go-fr.html.markdown index 9d8bef70..38cc3b52 100644 --- a/fr-fr/go-fr.html.markdown +++ b/fr-fr/go-fr.html.markdown @@ -32,7 +32,7 @@ communauté active. multiligne */ // Un paquet débute avec une clause "package" -// "Main" est un nom spécial déclarant un paquet de type exécutable plutôt +// "main" est un nom spécial déclarant un paquet de type exécutable plutôt // qu'une bibliothèque package main diff --git a/go.html.markdown b/go.html.markdown index c040b3ee..fe69ed43 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -39,7 +39,7 @@ Go comes with a good standard library and a sizeable community. // +build prod, dev, test // A package clause starts every source file. -// Main is a special name declaring an executable rather than a library. +// main is a special name declaring an executable rather than a library. package main // Import declaration declares library packages referenced in this file. diff --git a/it-it/go-it.html.markdown b/it-it/go-it.html.markdown index 797f6b0b..2af2468d 100644 --- a/it-it/go-it.html.markdown +++ b/it-it/go-it.html.markdown @@ -34,7 +34,7 @@ Go include un'ottima libreria standard e ha una community entusiasta. su riga multipla */ // In cima ad ogni file è necessario specificare il package. -// Main è un package speciale che identifica un eseguibile anziché una libreria. +// main è un package speciale che identifica un eseguibile anziché una libreria. package main // Con import sono dichiarate tutte le librerie a cui si fa riferimento diff --git a/pt-br/go-pt.html.markdown b/pt-br/go-pt.html.markdown index 31473ee1..f68d63eb 100644 --- a/pt-br/go-pt.html.markdown +++ b/pt-br/go-pt.html.markdown @@ -28,7 +28,7 @@ Go vem com uma biblioteca padrão exaustiva e uma comunidade entusiasta. várias linhas */ // A cláusula package aparece no início de cada arquivo. -// Main é um nome especial declarando um executável ao invés de uma biblioteca. +// main é um nome especial declarando um executável ao invés de uma biblioteca. package main // A cláusula Import declara os pacotes referenciados neste arquivo. diff --git a/ru-ru/go-ru.html.markdown b/ru-ru/go-ru.html.markdown index 37592258..8d2eac90 100644 --- a/ru-ru/go-ru.html.markdown +++ b/ru-ru/go-ru.html.markdown @@ -29,7 +29,7 @@ Go - это язык общего назначения, целью которо комментарий */ // Ключевое слово package присутствует в начале каждого файла. -// Main это специальное имя, обозначающее исполняемый файл, нежели библиотеку. +// main это специальное имя, обозначающее исполняемый файл, нежели библиотеку. package main // Import предназначен для указания зависимостей этого файла. diff --git a/zh-cn/go-cn.html.markdown b/zh-cn/go-cn.html.markdown index dd52d187..0123c0a6 100644 --- a/zh-cn/go-cn.html.markdown +++ b/zh-cn/go-cn.html.markdown @@ -22,7 +22,7 @@ Go语言有非常棒的标准库,还有一个充满热情的社区。 注释 */ // 导入包的子句在每个源文件的开头。 -// Main比较特殊,它用来声明可执行文件,而不是一个库。 +// main比较特殊,它用来声明可执行文件,而不是一个库。 package main // Import语句声明了当前文件引用的包。 -- cgit v1.2.3 From 5f941a4dee3ae57914d7b506a3ea2f42d14dd7f4 Mon Sep 17 00:00:00 2001 From: wang sy Date: Sat, 14 Jan 2023 13:42:05 +0800 Subject: Fix broken 4clojure links --- clojure.html.markdown | 2 +- es-es/clojure-es.html.markdown | 2 +- fr-fr/clojure-fr.html.markdown | 2 +- ko-kr/clojure-kr.html.markdown | 2 +- ms-my/clojure-my.html.markdown | 2 +- pt-br/clojure-pt.html.markdown | 2 +- ro-ro/clojure-ro.html.markdown | 2 +- ru-ru/clojure-ru.html.markdown | 2 +- tr-tr/clojure-tr.html.markdown | 2 +- zh-cn/clojure-cn.html.markdown | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clojure.html.markdown b/clojure.html.markdown index 20812a9b..21d5a088 100644 --- a/clojure.html.markdown +++ b/clojure.html.markdown @@ -412,7 +412,7 @@ Clojuredocs.org has documentation with examples for most core functions: [http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core) 4Clojure is a great way to build your clojure/FP skills: -[http://www.4clojure.com/](http://www.4clojure.com/) +[https://4clojure.oxal.org/](https://4clojure.oxal.org/) Clojure-doc.org (yes, really) has a number of getting started articles: [http://clojure-doc.org/](http://clojure-doc.org/) diff --git a/es-es/clojure-es.html.markdown b/es-es/clojure-es.html.markdown index 62935ebe..9f25425c 100644 --- a/es-es/clojure-es.html.markdown +++ b/es-es/clojure-es.html.markdown @@ -431,7 +431,7 @@ funciones principales (pertenecientes al core): [http://clojuredocs.org/quickref](http://clojuredocs.org/quickref) 4Clojure es una genial forma de mejorar tus habilidades con clojure/FP: -[http://www.4clojure.com/](http://www.4clojure.com/) +[https://4clojure.oxal.org/](https://4clojure.oxal.org/) Clojure-doc.org (sí, de verdad) tiene un buen número de artículos con los que iniciarse en Clojure: [http://clojure-doc.org](http://clojure-doc.org) diff --git a/fr-fr/clojure-fr.html.markdown b/fr-fr/clojure-fr.html.markdown index 65747c0d..6215e0cf 100644 --- a/fr-fr/clojure-fr.html.markdown +++ b/fr-fr/clojure-fr.html.markdown @@ -427,7 +427,7 @@ plupart des fonctions principales : 4Clojure est une super manière d'augmenter vos compétences en Clojure et en programmation fonctionnelle : -[http://www.4clojure.com/](http://www.4clojure.com/) +[https://4clojure.oxal.org/](https://4clojure.oxal.org/) Clojure-doc.org a pas mal d'article pour débuter : [http://clojure-doc.org/](http://clojure-doc.org/) diff --git a/ko-kr/clojure-kr.html.markdown b/ko-kr/clojure-kr.html.markdown index 1d9e53cd..32a5baf3 100644 --- a/ko-kr/clojure-kr.html.markdown +++ b/ko-kr/clojure-kr.html.markdown @@ -377,7 +377,7 @@ Clojuredocs.org는 core 함수들에 대해 다양한 예제와 문서를 보유 [http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core) 4Clojure는 clojure/FP 스킬을 올릴 수 있는 좋은 길입니다: -[http://www.4clojure.com/](http://www.4clojure.com/) +[https://4clojure.oxal.org/](https://4clojure.oxal.org/) Clojure-doc.org는 많고 많은 문서들을 보유하고 있습니다: [http://clojure-doc.org/](http://clojure-doc.org/) diff --git a/ms-my/clojure-my.html.markdown b/ms-my/clojure-my.html.markdown index e199c8f4..cfcdeb40 100644 --- a/ms-my/clojure-my.html.markdown +++ b/ms-my/clojure-my.html.markdown @@ -413,7 +413,7 @@ Clojuredocs.org mempunyai dokumentasi berserta contoh untuk menggunakan kebanyak [http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core) 4Clojure ialah cara yang baik untuk mengasah skill Clojure dan functional programming: -[http://www.4clojure.com/](http://www.4clojure.com/) +[https://4clojure.oxal.org/](https://4clojure.oxal.org/) Clojure-doc.org (yup, serius) juga mengandungi beberapa artikel sebagai permulaan: [http://clojure-doc.org/](http://clojure-doc.org/) diff --git a/pt-br/clojure-pt.html.markdown b/pt-br/clojure-pt.html.markdown index e40b8fe7..15ad930a 100644 --- a/pt-br/clojure-pt.html.markdown +++ b/pt-br/clojure-pt.html.markdown @@ -561,7 +561,7 @@ Caso queira aprender mais: [http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core) * 4clojure possui alguns problemas e desafios interessantes para quem quiser treinar clojure ou programação funcional: -[http://www.4clojure.com/](http://www.4clojure.com/) +[https://4clojure.oxal.org/](https://4clojure.oxal.org/) * clojure-doc.org tem um bom número de artigos para iniciantes: [http://clojure-doc.org/](http://clojure-doc.org/) diff --git a/ro-ro/clojure-ro.html.markdown b/ro-ro/clojure-ro.html.markdown index 32ba9620..77052379 100644 --- a/ro-ro/clojure-ro.html.markdown +++ b/ro-ro/clojure-ro.html.markdown @@ -380,7 +380,7 @@ Clojuredocs.org contine documentatie cu exemple pentru majoritatea functiilor de [http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core) 4Clojure este o metoda excelenta pentru a exersa Clojure/FP (Programarea Functionala): -[http://www.4clojure.com/](http://www.4clojure.com/) +[https://4clojure.oxal.org/](https://4clojure.oxal.org/) Clojure-doc.org are un numar de article pentru incepatori: [http://clojure-doc.org/](http://clojure-doc.org/) diff --git a/ru-ru/clojure-ru.html.markdown b/ru-ru/clojure-ru.html.markdown index 19233d23..66986fa0 100644 --- a/ru-ru/clojure-ru.html.markdown +++ b/ru-ru/clojure-ru.html.markdown @@ -421,7 +421,7 @@ Clojuredocs.org — сайт документации языка с пример [http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core) 4Clojure — отличный способ закрепить навыки программирования на clojure, решая задачи вместе с коллегами со всего мира: -[http://www.4clojure.com/](http://www.4clojure.com/) +[https://4clojure.oxal.org/](https://4clojure.oxal.org/) Clojure-doc.org (да, именно) неплохой перечень статей для начинающих: [http://clojure-doc.org/](http://clojure-doc.org/) diff --git a/tr-tr/clojure-tr.html.markdown b/tr-tr/clojure-tr.html.markdown index 5ebe5ce6..d21947ee 100644 --- a/tr-tr/clojure-tr.html.markdown +++ b/tr-tr/clojure-tr.html.markdown @@ -482,7 +482,7 @@ Clojuredocs.org, örneklerle bezenmiş Clojure dökümantasyonu: [http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core) 4Clojure, interaktif bir şekilde FP ve Clojure yeteneklerinizi geliştirmenize olanak veriyor: -[http://www.4clojure.com/](http://www.4clojure.com/) +[https://4clojure.oxal.org/](https://4clojure.oxal.org/) Clojure-doc.org, Başlangıç için bir içeriklere sahip: [http://clojure-doc.org/](http://clojure-doc.org/) diff --git a/zh-cn/clojure-cn.html.markdown b/zh-cn/clojure-cn.html.markdown index fa241384..e98eac2a 100644 --- a/zh-cn/clojure-cn.html.markdown +++ b/zh-cn/clojure-cn.html.markdown @@ -362,7 +362,7 @@ Clojuredocs.org有大多数核心函数的文档,还带了示例哦: [http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core) 4Clojure是个很赞的用来练习clojure/FP技能的地方: -[http://www.4clojure.com/](http://www.4clojure.com/) +[https://4clojure.oxal.org/](https://4clojure.oxal.org/) Clojure-doc.org (你没看错)有很多入门级的文章: [http://clojure-doc.org/](http://clojure-doc.org/) -- cgit v1.2.3 From 1ef779974acd118d77fab755ca5fb0540b61afe6 Mon Sep 17 00:00:00 2001 From: 0-pal <31777176+0-pal@users.noreply.github.com> Date: Tue, 17 Jan 2023 16:27:36 +0100 Subject: Update yaml-de.html.markdown Corrected minor typo: "Zeiangaben" -> "Zeitangaben" --- de-de/yaml-de.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/de-de/yaml-de.html.markdown b/de-de/yaml-de.html.markdown index 0332c912..00e4fd94 100644 --- a/de-de/yaml-de.html.markdown +++ b/de-de/yaml-de.html.markdown @@ -112,7 +112,7 @@ python_komplexe_Zahlen: !!python/komplex 1+2j #################### # Strings und Zahlen sind nicht die einzigen Skalare, welche YAML versteht. -# ISO-formatierte Datumsangaben and Zeiangaben können ebenso geparsed werden. +# ISO-formatierte Datumsangaben and Zeitangaben können ebenso geparsed werden. DatumZeit: 2001-12-15T02:59:43.1Z DatumZeit_mit_Leerzeichen: 2001-12-14 21:59:43.10 -5 Datum: 2002-12-14 -- cgit v1.2.3 From b63cb12fa3826ea8ed346b56ccbe3dd424e679e6 Mon Sep 17 00:00:00 2001 From: luovkle Date: Sat, 21 Jan 2023 00:24:42 -0600 Subject: [python/es-es] parentheses required in print functions are added --- es-es/python-es.html.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/es-es/python-es.html.markdown b/es-es/python-es.html.markdown index 7deec286..5c95854f 100644 --- a/es-es/python-es.html.markdown +++ b/es-es/python-es.html.markdown @@ -388,8 +388,8 @@ keyword_args(pie="grande", lago="ness") #=> {"pie": "grande", "lago": "ness"} # Puedes hacer ambas a la vez si quieres def todos_los_argumentos(*args, **kwargs): - print args - print kwargs + print(args) + print(kwargs) """ todos_los_argumentos(1, 2, a=3, b=4) imprime: (1, 2) @@ -462,10 +462,10 @@ class Humano(object): # Instancia una clase i = Humano(nombre="Ian") -print i.decir("hi") # imprime "Ian: hi" +print(i.decir("hi")) # imprime "Ian: hi" j = Humano("Joel") -print j.decir("hello") #imprime "Joel: hello" +print(j.decir("hello")) #imprime "Joel: hello" # Llama nuestro método de clase i.get_especie() #=> "H. sapiens" -- cgit v1.2.3 From dae4b39cbf7fe585e67bfb5373f2830a3801a95d Mon Sep 17 00:00:00 2001 From: Darlington02 Date: Mon, 23 Jan 2023 10:24:45 +0100 Subject: Added Cairo-lang --- cairo.html.markdown | 714 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 714 insertions(+) create mode 100644 cairo.html.markdown diff --git a/cairo.html.markdown b/cairo.html.markdown new file mode 100644 index 00000000..25ef91aa --- /dev/null +++ b/cairo.html.markdown @@ -0,0 +1,714 @@ +--- +language: Cairo +filename: learnCairo.sol +contributors: + - ["Darlington Nnam", "https://github.com/Darlington02"] +--- + +# Cairo +Cairo is StarkNet's native language and the first Turing-complete language for scripting provable programs (where one party can prove to another that a certain computation was executed correctly) for general computations. +# StarkNet +StarkNet is a decentralized ZK-rollup that operates as an Ethereum layer 2 chain. StarkNet enables Decentralized applications to achieve unlimited scale for their computation - without compromising Ethereum's decentralization and security, thereby solving the Scalability Trilemma. + +In this document, we are going to be going in-depth into understanding Cairo's syntax and how you could create and deploy a Cairo smart contract on StarkNet. + +**NB: As at the time of this writing, StarkNet is still at v0.10.3, with Cairo 1.0 coming soon. The ecosystem is young and evolving very fast, so you might want to check the [official docs](https://www.cairo-lang.org/docs) to confirm this document is still up-to-date. Pull requests are welcome!** + +# Setting Up A Development Environment +Before we get started writing codes, we will need to setup a Cairo development environment, for writing, compiling and deploying our contracts to StarkNet. +For the purpose of this tutorial we are going to be using the [Protostar Framework](https://github.com/software-mansion/protostar). Installation steps can be found in the docs [here](https://docs.swmansion.com/protostar/docs/tutorials/installation). +Note that Protostar supports just Mac and Linux OS, Windows users might need to use WSL, or go for other alternatives such as the Official [StarkNet CLI](https://www.cairo-lang.org/docs/quickstart.html) or [Nile from Openzeppelin](https://github.com/OpenZeppelin/nile) + +Once you're done with the installations, run the command `protostar -v` to confirm your installation was successful. If successful, you should see your Protostar version displayed on the screen. + +## Initializing a new project +Protostar similar to Truffle for solidity development can be installed once and used for multiple projects. +To initialize a new Protostar project, run the following command: +``` +protostar init +``` + +2. It would then request the project's name and the library's directory name, you'd need to fill in this, and a new project will be initialized successfully. + +# Compiling, Declaring, Deploying And Interacting With StarkNet Contracts +For the purpose of this tutorial, head over to this [github repo](https://github.com/Darlington02/CairoLearnXinYminutes) and clone locally. + +Within the `src` folder you'll find a boilerplate contract that comes with initializing a new Protostar project, `main.cairo`. We are going to be compiling, declaring and deploying this contract. + +## Compiling Contracts +To compile a Cairo contract using Protostar, ensure a path to the contract is specified in the `[contracts]` section of the `protostar.toml` file. Once you've done that, open your terminal and run the command: +``` +protostar build +``` +And you should get an output similar to what you see below, with a `main.json` and `main_abi.json` files created in the `build` folder. +building your contract + +## Declaring Contracts +With the recent StarkNet update to 0.10.3, the DEPLOY transaction was deprecated and no longer works. To deploy a transaction, you must first declare a Contract to obtain the class hash, then deploy the declared contract using the [Universal Deployer Contract](https://community.starknet.io/t/universal-deployer-contract-proposal/1864). + +Before declaring or deploying your contract using Protostar, you should set the private key associated with the specified account address in a file, or in the terminal. To set your private key in the terminal, run the command: + +``` +export PROTOSTAR_ACCOUNT_PRIVATE_KEY=[YOUR PRIVATE KEY HERE] +``` + +Then to declare our contract using Protostar run the following command: +``` +protostar declare ./build/main.json --network testnet --account 0x0691622bBFD29e835bA4004e7425A4e9630840EbD11c5269DE51C16774585b16 --max-fee auto +``` + +where `network` specifies the network we are deploying to, `account` specifies account whose private key we are using, `max-fee` specifies the maximum fee to be paid for the transaction. You should get the class hash outputted as seen below: +declaring your contract + +## Deploying Contracts +After obtaining our class hash from declaring, we can now deploy using the below command: +``` +protostar deploy 0x02a5de1b145e18dfeb31c7cd7ff403714ededf5f3fdf75f8b0ac96f2017541bc --network testnet --account 0x0691622bBFD29e835bA4004e7425A4e9630840EbD11c5269DE51C16774585b16 --max-fee auto +``` + +where `0x02a5de1b145e18dfeb31c7cd7ff403714ededf5f3fdf75f8b0ac96f2017541bc` is the class hash of our contract. +deploying your contract + +## Interacting With Contracts +To interact with your deployed contract, we will be using Argent X (alternative - Braavos), and Starkscan (alternative - Voyager). To install and setup Argent X, check out this [guide](https://www.argent.xyz/learn/how-to-create-an-argent-x-wallet/). + +Copy your contract address, displayed on screen from the previous step, and head over to [Starkscan](https://testnet.starkscan.co/) to search for the contract. Once found, you can make write calls to the contract by following the steps below: +1. Click on the "connect wallet" button +connect wallet +2. Select Argent X and approve the connection +connect to argentX +3. You can now make read and write calls easily. + +# Let's learn Cairo +First let's look at a default contract that comes with Protostar +``` + // Allows you to set balanace on deployment, increase, and get the balance. + + // Language directive - instructs compiler its a StarkNet contract + %lang starknet + + // Library imports from the Cairo-lang library + from starkware.cairo.common.math import assert_nn + from starkware.cairo.common.cairo_builtins import HashBuiltin + + // @dev Storage variable that stores the balance of a user. + // @storage_var is a decorator that instructs the compiler the function below it is a storage variable. + @storage_var + func balance() -> (res: felt) { + } + + // @dev Constructor writes the balance variable to 0 on deployment + // Constructors sets storage variables on deployment. Can accept arguments too. + @constructor + func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { + balance.write(0); + return (); + } + + // @dev increase_balance updates the balance variable + // @param amount the amount you want to add to balance + // @external is a decorator that specifies the func below it is an external function. + @external + func increase_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + amount: felt + ) { + with_attr error_message("Amount must be positive. Got: {amount}.") { + assert_nn(amount); + } + + let (res) = balance.read(); + balance.write(res + amount); + return (); + } + + // @dev returns the balance variable + // @view is a decorator that specifies the func below it is a view function. + @view + func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (res: felt) { + let (res) = balance.read(); + return (res,); + } + + // before proceeding, try to build, deploy and interact with this contract! + // NB: Should be at main.cairo if you are using Protostar. + +``` +Now unto the main lessons + +### 1. THE FELT DATA TYPE +``` + // Unlike solidity, where you have access to various data types, Cairo comes with just a single data type..felts + // Felts stands for Field elements, and are a 252 bit integer in the range 0<=x<=P where P is a prime number. + // You can create a Uint256 in Cairo by utlizing a struct of two 128 bits felts. + + struct Uint256 { + low: felt, // The low 128 bits of the value. + high: felt, // The high 128 bits of the value. + } + + // To avoid running into issues with divisions, it's safer to work with the unsigned_div_rem method from Cairo-lang's library. +``` + +### 2. LANG DIRECTIVE AND IMPORTS +``` + // To get started with writing a StarkNet contract, you must specify the directive: + + %lang starknet + + // This directive informs the compiler you are writing a contract and not a program. + // The difference between both is contracts have access to StarkNet's storage, programs don't and as such are stateless. + + // There are important functions you might need to import from the official Cairo-lang library or Openzeppelin's. e.g. + + from starkware.cairo.common.cairo_builtins import HashBuiltin + from cairo_contracts.src.openzeppelin.token.erc20.library import ERC20 + from starkware.cairo.common.uint256 import Uint256 + from starkware.cairo.common.bool import TRUE +``` + +### 3. DATA STRUCTURES +``` + // A. STORAGE VARIABLES + // Cairo's storage is a map with 2^251 slots, where each slot is a felt which is initialized to 0. + // You create one using the @storage_var decorator + + @storage_var + func names() -> (name: felt){ + } + + // B. STORAGE MAPPINGS + // Unlike soldity where mappings have a separate keyword, in Cairo you create mappings using storage variables. + + @storage_var + func names(address: felt) -> (name: felt){ + } + + // C. STRUCTS + // Structs are a means to create custom data types in Cairo. + // A Struct has a size, which is the sum of the sizes of its members. The size can be retrieved using MyStruct.SIZE. + // You create a struct in Cairo using the `struct` keyword. + + struct Person { + name: felt, + age: felt, + address: felt, + } + + // D. CONSTANTS + // Constants are fixed and as such can't be altered after being set. + // They evaluate to an integer (field element) at compile time. + // To create a constant in Cairo, you use the `const` keyword. + // Its proper practice to capitalize constant names. + + const USER = 0x01C6cfC1DB2ae90dACEA243F0a8C2F4e32560F7cDD398e4dA2Cc56B733774E9b + + // E. ARRAYS + // Arrays can be defined as a pointer(felt*) to the first element of the array. + // As an array is populated, its elements take up contigous memory cells. + // The `alloc` keyword can be used to dynamically allocate a new memory segment, which can be used to store an array + + let (myArray: felt*) = alloc (); + assert myArray[0] = 1; + assert myArray[1] = 2; + assert myArray[3] = 3; + + // You can also use the `new` operator to create fixed-size arrays using tuples + // The new operator is useful as it enables you allocate memory and initialize the object in one instruction + + func foo() { + tempvar arr: felt* = new (1, 1, 2, 3, 5); + assert arr[4] = 5; + return (); + } + + // F. TUPLES + // A tuple is a finite, ordered, unchangeable list of elements + // It is represented as a comma-separated list of elements enclosed by parentheses + // Their elements may be of any combination of valid types. + + local tuple0: (felt, felt, felt) = (7, 9, 13); + + // G. EVENTS + // Events allows a contract emit information during the course of its execution, that can be used outside of StarkNet. + // To create an event: + + @event + func name_stored(address, name) { + } + + // To emit an event: + + name_stored.emit(address, name); +``` + +### 4. CONSTRUCTORS, EXTERNAL AND VIEW FUNCTIONS +``` + // A. CONSTRUCTORS + // Constructors are a way to intialize state variables on contract deployment + // You create a constructor using the @constructor decorator + + @constructor + func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(_name: felt) { + let (caller) = get_caller_address(); + names.write(caller, _name); + return (); + } + + // B. EXTERNAL FUNCTIONS + // External functions are functions that modifies the state of the network + // You create an external function using the @external decorator + + @external + func store_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(_name: felt){ + let (caller) = get_caller_address(); + names.write(caller, _name); + stored_name.emit(caller, _name); + return (); + } + + // C. VIEW FUNCTIONS + // View functions do not modify the state of the blockchain + // You can create a view function using the @view decorator + + @view + func get_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(_address: felt) -> (name: felt){ + let (name) = names.read(_address); + return (name,); + } + + // NB: Unlike Solidity, Cairo supports just External and View function types. + // You can alternatively also create an internal function by not adding any decorator to the function. +``` + +### 5. DECORATORS +``` + // All functions in Cairo are specified by the `func` keyword, which can be confusing. + // Decorators are used by the compiler to distinguish between these functions. + + // Here are the most common decorators you'll encounter in Cairo: + + // 1. @storage_var — used for specifying state variables. + // 2. @constructor — used for specifying constructors. + // 3. @external — used for specifying functions that write to a state variable. + // 4. @event — used for specifying events + // 5. @view — used for specifying functions that reads from a state variable. + // 6. @contract_interface - used for specifying function interfaces. + // 7. @l1_handler — used for specifying functions that processes message sent from an L1 contract in a messaging bridge. +``` + +### 6. BUILTINS, HINTS & IMPLICIT ARGUMENTS +``` + // A. BUILTINS + // Builtins are predefined optimized low-level execution units, which are added to Cairo’s CPU board. + // They help perform predefined computations like pedersen hashing, bitwise operations etc, which are expensive to perform in Vanilla Cairo. + // Each builtin in Cairo, is assigned a separate memory location, accessible through regular Cairo memory calls using implicit parameters. + // You specify them using the %builtins directive + + // Here is a list of available builtins in Cairo: + // 1. output — the output builtin is used for writing program outputs + // 2. pedersen — the pedersen builtin is used for pedersen hashing computations + // 3. range_check — This builtin is mostly used for integer comparisons, and facilitates check to confirm that a field element is within a range [0, 2^128) + // 4. ecdsa — the ecdsa builtin is used for verifying ECDSA signatures + // 5. bitwise — the bitwise builtin is used for carrying out bitwise operations on felts + + // B. HINTS + // Hints are pieces of Python codes, which contains instructions that only the prover sees and executes + // From the point of view of the verifier these hints do not exist + // To specify a hint in Cairo, you need to encapsulate it within %{ and%} + // Its good practice to avoid using hints as much as you can in your contracts, as hints are not added to the bytecode, and thus do not count in the total number of execution steps. + + %{ + # Python hint goes here + %} + + // C. IMPLICIT ARGUMENTS + // Implicit arguments are not restricted to the function body, but can be inherited by other functions calls that require them. + // Implicit arguments are passed in between curly bracelets, like you can see below: + + func store_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(_name: felt){ + let (caller) = get_caller_address(); + names.write(caller, _name); + stored_name.emit(caller, _name); + return (); + } +``` + +### 7. ERROR MESSAGES & ACCESS CONTROLS +``` + // You can create custom errors in Cairo which is outputted to the user upon failed execution. + // This can be very useful for implementing checks and proper access control mechanisms. + // An example is preventing a user to call a function except user is admin. + + // imports + from starkware.starknet.common.syscalls import get_caller_address + + // create an admin constant + const ADMIN = 0x01C6cfC1DB2ae90dACEA243F0a8C2F4e32560F7cDD398e4dA2Cc56B733774E9b + + // implement access control + with_attr error_message("You do not have access to make this action!"){ + let (caller) = get_caller_address(); + assert ADMIN = caller; + } + + // using an assert statement throws if condition is not true, thus returning the specified error. +``` + +### 8. CONTRACT INTERFACES +``` + // Contract interfaces provide a means for one contract to invoke or call the external function of another contract. + // To create a contract interface, you use the @contract_interface keyword + + @contract_interface + namespace IENS { + func store_name(_name: felt) { + } + + func get_name(_address: felt) -> (name: felt) { + } + } + + // Once a contract interface is specified, any contract can make calls to that contract passing in the contract address as the first parameter like this: + + IENS.store_name(contract_address, _name); + + // Note that Interfaces excludes the function body/logic and the implicit arguments. +``` + +### 9. RECURSIONS +``` + // Due to the unavailability of loops, Recursions are the go-to for similar operations. + // In simple terms, a recursive function is one which calls itself repeatedly. + + // A good example to demonstrate this is writing a function for getting the nth fibonacci number: + + @external + func fibonacci{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(n : felt) -> (result : felt){ + alloc_locals; + if (n == 0){ + return (0); + } + if (n == 1){ + return (1); + } + let (local x) = fibonacci(n - 1); + let (local y) = fibonacci(n - 2); + return (result=(x + y)); + } + + // The nth fibonacci term is the sum of the nth - 1 and the nth - 2 numbers, that's why we get these two as (x, y) using recursion. + // NB: when implementing recursive functions, always remember to implement a base case (n==0, n==1 in our case), to prevent stack overflow. +``` + +Some low-level stuffs + +### 10. REGISTERS +``` + // Registers holds values that may change over time. + + // There are 3 major types of Registers: + // 1. ap (allocation pointer) points to a yet unused memory. Temporary variables created using `let`, `tempvar` are held here, and thus susceptible to being revoked + // 2. fp (frame pointer) points to the frame of the current function. The address of all the function arguments and local variables are relative to this register and as such can never be revoked + // 3. pc (program counter) points to the current instruction +``` + +### 11. REVOKED REFERENCES +``` + // Revoked references occurs when there is a call instruction to another function, between the definition of a reference variable that depends on `ap`(temp variables) and its usage. This occurs as the compiler may not be able to compute the change of `ap` (as one may jump to the label from another place in the program, or call a function that might change ap in an unknown way). + + // Here is an example to demonstrate what I mean: + + @external + func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (res: felt) { + return (res=100); + } + + @external + func double_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (res: felt) { + let multiplier = 2; + let (balance) = get_balance(); + let new_balance = balance * multiplier; + return (res=new_balance); + } + + // If you run that code, you'll run into the revoked reference error as we are trying to access the `multiplier` variable after calling the get_balance function; + + // To solve revoked references, In simple cases you can resolve this issue, by adding the keyword, `alloc_locals` within function scopes, but in most complex cases you might need to create a local variable to resolve it. + + // resolving the `double_balance` function: + @external + func double_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (res: felt) { + alloc_locals; + let multiplier = 2; + let (balance) = get_balance(); + let new_balance = balance * multiplier; + return (res=new_balance); + } +``` + +Miscellaneous + +### 12. Understanding Cairo's punctuations +``` + // ; (semicolon). Used at the end of each instruction + + // ( ) (parentheses). Used in a function declaration, if statements, and in a tuple declaration + + // { } (curly brackets). Used in a declaration of implicit arguments and to define code blocks. + + // [ ] (square brackets). Standalone brackets represent the value at a particular address location (such as the allocation pointer, [ap]). Brackets following a pointer or a tuple act as a subscript operator, where x[2] represents the element with index 2 in x. + + // * Single asterisk. Refers to the pointer of an expression. + + // % Percent sign. Appears at the start of a directive, such as %builtins or %lang. + + // %{ %} Represents Python hints. + + // _ (underscore). A placeholder to handle values that are not used, such as an unused function return value. +``` + +# FULL CONTRACT EXAMPLE +Below is a simple automated market maker contract example that implements most of what we just learnt! Re-write, deploy, have fun! +``` + %lang starknet + + from starkware.cairo.common.cairo_builtins import HashBuiltin + from starkware.cairo.common.hash import hash2 + from starkware.cairo.common.alloc import alloc + from starkware.cairo.common.math import (assert_le, assert_nn_le, unsigned_div_rem) + from starkware.starknet.common.syscalls import (get_caller_address, storage_read, storage_write) + + // + // CONSTANTS + // + + + // @dev the maximum amount of each token that belongs to the AMM + const BALANCE_UPPER_BOUND = 2 ** 64; + + const TOKEN_TYPE_A = 1; + const TOKEN_TYPE_B = 2; + + // @dev Ensure the user's balances are much smaller than the pool's balance + const POOL_UPPER_BOUND = 2 ** 30; + const ACCOUNT_BALANCE_BOUND = 1073741; // (2 ** 30 / 1000) + + // + // STORAGE VARIABLES + // + + // @dev A map from account and token type to corresponding balance + @storage_var + func account_balance(account_id: felt, token_type: felt) -> (balance: felt) { + } + + // @dev a map from token type to corresponding pool balance + @storage_var + func pool_balance(token_type: felt) -> (balance: felt) { + } + + // + // GETTERS + // + + // @dev returns account balance for a given token + // @param account_id Account to be queried + // @param token_type Token to be queried + @view + func get_account_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + account_id: felt, token_type: felt + ) -> (balance: felt) { + return account_balance.read(account_id, token_type); + } + + // @dev return the pool's balance + // @param token_type Token type to get pool balance + @view + func get_pool_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + token_type: felt + ) -> (balance: felt) { + return pool_balance.read(token_type); + } + + // + // EXTERNALS + // + + // @dev set pool balance for a given token + // @param token_type Token whose balance is to be set + // @param balance Amount to be set as balance + @external + func set_pool_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + token_type: felt, balance: felt + ) { + with_attr error_message("exceeds maximum allowed tokens!"){ + assert_nn_le(balance, BALANCE_UPPER_BOUND - 1); + } + + pool_balance.write(token_type, balance); + return (); + } + + // @dev add demo token to the given account + // @param token_a_amount amount of token a to be added + // @param token_b_amount amount of token b to be added + @external + func add_demo_token{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + token_a_amount: felt, token_b_amount: felt + ) { + alloc_locals; + let (account_id) = get_caller_address(); + + modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_A, amount=token_a_amount); + modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_B, amount=token_b_amount); + + return (); + } + + // @dev intialize AMM + // @param token_a amount of token a to be set in pool + // @param token_b amount of token b to be set in pool + @external + func init_pool{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + token_a: felt, token_b: felt + ) { + with_attr error_message("exceeds maximum allowed tokens!"){ + assert_nn_le(token_a, POOL_UPPER_BOUND - 1); + assert_nn_le(token_b, POOL_UPPER_BOUND - 1); + } + + set_pool_token_balance(token_type=TOKEN_TYPE_A, balance=token_a); + set_pool_token_balance(token_type=TOKEN_TYPE_B, balance=token_b); + + return (); + } + + + // @dev swaps token between the given account and the pool + // @param token_from token to be swapped + // @param amount_from amount of token to be swapped + // @return amount_to the token swapped to + @external + func swap{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + token_from: felt, amount_from: felt + ) -> (amount_to: felt) { + alloc_locals; + let (account_id) = get_caller_address(); + + // verify token_from is TOKEN_TYPE_A or TOKEN_TYPE_B + with_attr error_message("token not allowed in pool!"){ + assert (token_from - TOKEN_TYPE_A) * (token_from - TOKEN_TYPE_B) = 0; + } + + // check requested amount_from is valid + with_attr error_message("exceeds maximum allowed tokens!"){ + assert_nn_le(amount_from, BALANCE_UPPER_BOUND - 1); + } + + // check user has enough funds + let (account_from_balance) = get_account_token_balance(account_id=account_id, token_type=token_from); + with_attr error_message("insufficient balance!"){ + assert_le(amount_from, account_from_balance); + } + + let (token_to) = get_opposite_token(token_type=token_from); + let (amount_to) = do_swap(account_id=account_id, token_from=token_from, token_to=token_to, amount_from=amount_from); + + return (amount_to=amount_to); + } + + + // + // INTERNALS + // + + // @dev internal function that updates account balance for a given token + // @param account_id Account whose balance is to be modified + // @param token_type Token type to be modified + // @param amount Amount Amount to be added + func modify_account_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + account_id: felt, token_type: felt, amount: felt + ) { + let (current_balance) = account_balance.read(account_id, token_type); + tempvar new_balance = current_balance + amount; + + with_attr error_message("exceeds maximum allowed tokens!"){ + assert_nn_le(new_balance, BALANCE_UPPER_BOUND - 1); + } + + account_balance.write(account_id=account_id, token_type=token_type, value=new_balance); + return (); + } + + // @dev internal function that swaps tokens between the given account and the pool + // @param account_id Account whose tokens are to be swapped + // @param token_from Token type to be swapped from + // @param token_to Token type to be swapped to + // @param amount_from Amount to be swapped + func do_swap{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + account_id: felt, token_from: felt, token_to: felt, amount_from: felt + ) -> (amount_to: felt) { + alloc_locals; + + // get pool balance + let (local amm_from_balance) = get_pool_token_balance(token_type = token_from); + let (local amm_to_balance) = get_pool_token_balance(token_type=token_to); + + // calculate swap amount + let (local amount_to, _) = unsigned_div_rem((amm_to_balance * amount_from), (amm_from_balance + amount_from)); + + // update token_from balances + modify_account_balance(account_id=account_id, token_type=token_from, amount=-amount_from); + set_pool_token_balance(token_type=token_from, balance=(amm_from_balance + amount_from)); + + // update token_to balances + modify_account_balance(account_id=account_id, token_type=token_to, amount=amount_to); + set_pool_token_balance(token_type=token_to, balance=(amm_to_balance - amount_to)); + + return (amount_to=amount_to); + } + + // @dev internal function to get the opposite token type + // @param token_type Token whose opposite pair needs to be gotten + func get_opposite_token(token_type: felt) -> (t: felt) { + if(token_type == TOKEN_TYPE_A) { + return (t=TOKEN_TYPE_B); + } else { + return (t=TOKEN_TYPE_A); + } + } +``` + +# Additional Resources +1. [Official documentation](https://www.cairo-lang.org/docs/) +2. [Starknet EDU](https://medium.com/starknet-edu) +3. [Journey through Cairo](https://medium.com/@darlingtonnnam/journey-through-cairo-i-setting-up-protostar-and-argentx-for-local-development-ba40ae6c5524) +4. [Demystifying Cairo whitepaper](https://medium.com/@pban/demystifying-cairo-white-paper-part-i-b71976ad0108) +5. [Learn about StarkNet with Argent](https://www.argent.xyz/learn/tag/starknet/) + +# Development Frameworks +1. [Protostar](https://docs.swmansion.com/protostar/docs/tutorials/installation) +2. [Nile](https://github.com/OpenZeppelin/nile) +3. [StarkNet CLI](https://www.cairo-lang.org/docs/quickstart.html) + +# Helpful Libraries +1. [Cairo-lang](https://github.com/starkware-libs/cairo-lang) +2. [Openzeppelin](https://github.com/OpenZeppelin/cairo-contracts) + +# Educational Repos +1. [StarkNet Cairo 101](https://github.com/starknet-edu/starknet-cairo-101) +2. [StarkNet ERC721](https://github.com/starknet-edu/starknet-erc721) +3. [StarkNet ERC20](https://github.com/starknet-edu/starknet-erc20) +4. [L1 -> L2 Messaging](https://github.com/starknet-edu/starknet-messaging-bridge) +5. [StarkNet Debug](https://github.com/starknet-edu/starknet-debug) +6. [StarkNet Accounts](https://github.com/starknet-edu/starknet-accounts) +7. [Min-Starknet](https://github.com/Darlington02/min-starknet) + +# Security +1. [Amarna static analysis for Cairo programs](https://blog.trailofbits.com/2022/04/20/amarna-static-analysis-for-cairo-programs/) +2. [Cairo and StarkNet security by Ctrl03](https://ctrlc03.github.io/) +3. [How to hack almost any Cairo smart contract](https://medium.com/ginger-security/how-to-hack-almost-any-starknet-cairo-smart-contract-67b4681ac0f6) +4. [Analyzing Cairo code using Armana](https://dic0de.substack.com/p/analyzing-cairo-code-using-amarna?sd=pf) + +# Future TO-DOs +Update tutorial to fit Cairo 1.0 \ No newline at end of file -- cgit v1.2.3 From 4460ef9bb67f8fb88707e151d39b5641ed3eeb08 Mon Sep 17 00:00:00 2001 From: Adam Bard Date: Fri, 27 Jan 2023 21:12:45 -0800 Subject: Add LICENSE.txt Text of the CC-3.0 SA license added as license.txt (source: https://creativecommons.org/licenses/by-sa/3.0/legalcode.txt) --- LICENSE.txt | 359 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..604209a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,359 @@ +Creative Commons Legal Code + +Attribution-ShareAlike 3.0 Unported + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR + DAMAGES RESULTING FROM ITS USE. + +License + +THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE +COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY +COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS +AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + +BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE +TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY +BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS +CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND +CONDITIONS. + +1. Definitions + + a. "Adaptation" means a work based upon the Work, or upon the Work and + other pre-existing works, such as a translation, adaptation, + derivative work, arrangement of music or other alterations of a + literary or artistic work, or phonogram or performance and includes + cinematographic adaptations or any other form in which the Work may be + recast, transformed, or adapted including in any form recognizably + derived from the original, except that a work that constitutes a + Collection will not be considered an Adaptation for the purpose of + this License. For the avoidance of doubt, where the Work is a musical + work, performance or phonogram, the synchronization of the Work in + timed-relation with a moving image ("synching") will be considered an + Adaptation for the purpose of this License. + b. "Collection" means a collection of literary or artistic works, such as + encyclopedias and anthologies, or performances, phonograms or + broadcasts, or other works or subject matter other than works listed + in Section 1(f) below, which, by reason of the selection and + arrangement of their contents, constitute intellectual creations, in + which the Work is included in its entirety in unmodified form along + with one or more other contributions, each constituting separate and + independent works in themselves, which together are assembled into a + collective whole. A work that constitutes a Collection will not be + considered an Adaptation (as defined below) for the purposes of this + License. + c. "Creative Commons Compatible License" means a license that is listed + at https://creativecommons.org/compatiblelicenses that has been + approved by Creative Commons as being essentially equivalent to this + License, including, at a minimum, because that license: (i) contains + terms that have the same purpose, meaning and effect as the License + Elements of this License; and, (ii) explicitly permits the relicensing + of adaptations of works made available under that license under this + License or a Creative Commons jurisdiction license with the same + License Elements as this License. + d. "Distribute" means to make available to the public the original and + copies of the Work or Adaptation, as appropriate, through sale or + other transfer of ownership. + e. "License Elements" means the following high-level license attributes + as selected by Licensor and indicated in the title of this License: + Attribution, ShareAlike. + f. "Licensor" means the individual, individuals, entity or entities that + offer(s) the Work under the terms of this License. + g. "Original Author" means, in the case of a literary or artistic work, + the individual, individuals, entity or entities who created the Work + or if no individual or entity can be identified, the publisher; and in + addition (i) in the case of a performance the actors, singers, + musicians, dancers, and other persons who act, sing, deliver, declaim, + play in, interpret or otherwise perform literary or artistic works or + expressions of folklore; (ii) in the case of a phonogram the producer + being the person or legal entity who first fixes the sounds of a + performance or other sounds; and, (iii) in the case of broadcasts, the + organization that transmits the broadcast. + h. "Work" means the literary and/or artistic work offered under the terms + of this License including without limitation any production in the + literary, scientific and artistic domain, whatever may be the mode or + form of its expression including digital form, such as a book, + pamphlet and other writing; a lecture, address, sermon or other work + of the same nature; a dramatic or dramatico-musical work; a + choreographic work or entertainment in dumb show; a musical + composition with or without words; a cinematographic work to which are + assimilated works expressed by a process analogous to cinematography; + a work of drawing, painting, architecture, sculpture, engraving or + lithography; a photographic work to which are assimilated works + expressed by a process analogous to photography; a work of applied + art; an illustration, map, plan, sketch or three-dimensional work + relative to geography, topography, architecture or science; a + performance; a broadcast; a phonogram; a compilation of data to the + extent it is protected as a copyrightable work; or a work performed by + a variety or circus performer to the extent it is not otherwise + considered a literary or artistic work. + i. "You" means an individual or entity exercising rights under this + License who has not previously violated the terms of this License with + respect to the Work, or who has received express permission from the + Licensor to exercise rights under this License despite a previous + violation. + j. "Publicly Perform" means to perform public recitations of the Work and + to communicate to the public those public recitations, by any means or + process, including by wire or wireless means or public digital + performances; to make available to the public Works in such a way that + members of the public may access these Works from a place and at a + place individually chosen by them; to perform the Work to the public + by any means or process and the communication to the public of the + performances of the Work, including by public digital performance; to + broadcast and rebroadcast the Work by any means including signs, + sounds or images. + k. "Reproduce" means to make copies of the Work by any means including + without limitation by sound or visual recordings and the right of + fixation and reproducing fixations of the Work, including storage of a + protected performance or phonogram in digital form or other electronic + medium. + +2. Fair Dealing Rights. Nothing in this License is intended to reduce, +limit, or restrict any uses free from copyright or rights arising from +limitations or exceptions that are provided for in connection with the +copyright protection under copyright law or other applicable laws. + +3. License Grant. Subject to the terms and conditions of this License, +Licensor hereby grants You a worldwide, royalty-free, non-exclusive, +perpetual (for the duration of the applicable copyright) license to +exercise the rights in the Work as stated below: + + a. to Reproduce the Work, to incorporate the Work into one or more + Collections, and to Reproduce the Work as incorporated in the + Collections; + b. to create and Reproduce Adaptations provided that any such Adaptation, + including any translation in any medium, takes reasonable steps to + clearly label, demarcate or otherwise identify that changes were made + to the original Work. For example, a translation could be marked "The + original work was translated from English to Spanish," or a + modification could indicate "The original work has been modified."; + c. to Distribute and Publicly Perform the Work including as incorporated + in Collections; and, + d. to Distribute and Publicly Perform Adaptations. + e. For the avoidance of doubt: + + i. Non-waivable Compulsory License Schemes. In those jurisdictions in + which the right to collect royalties through any statutory or + compulsory licensing scheme cannot be waived, the Licensor + reserves the exclusive right to collect such royalties for any + exercise by You of the rights granted under this License; + ii. Waivable Compulsory License Schemes. In those jurisdictions in + which the right to collect royalties through any statutory or + compulsory licensing scheme can be waived, the Licensor waives the + exclusive right to collect such royalties for any exercise by You + of the rights granted under this License; and, + iii. Voluntary License Schemes. The Licensor waives the right to + collect royalties, whether individually or, in the event that the + Licensor is a member of a collecting society that administers + voluntary licensing schemes, via that society, from any exercise + by You of the rights granted under this License. + +The above rights may be exercised in all media and formats whether now +known or hereafter devised. The above rights include the right to make +such modifications as are technically necessary to exercise the rights in +other media and formats. Subject to Section 8(f), all rights not expressly +granted by Licensor are hereby reserved. + +4. Restrictions. The license granted in Section 3 above is expressly made +subject to and limited by the following restrictions: + + a. You may Distribute or Publicly Perform the Work only under the terms + of this License. You must include a copy of, or the Uniform Resource + Identifier (URI) for, this License with every copy of the Work You + Distribute or Publicly Perform. You may not offer or impose any terms + on the Work that restrict the terms of this License or the ability of + the recipient of the Work to exercise the rights granted to that + recipient under the terms of the License. You may not sublicense the + Work. You must keep intact all notices that refer to this License and + to the disclaimer of warranties with every copy of the Work You + Distribute or Publicly Perform. When You Distribute or Publicly + Perform the Work, You may not impose any effective technological + measures on the Work that restrict the ability of a recipient of the + Work from You to exercise the rights granted to that recipient under + the terms of the License. This Section 4(a) applies to the Work as + incorporated in a Collection, but this does not require the Collection + apart from the Work itself to be made subject to the terms of this + License. If You create a Collection, upon notice from any Licensor You + must, to the extent practicable, remove from the Collection any credit + as required by Section 4(c), as requested. If You create an + Adaptation, upon notice from any Licensor You must, to the extent + practicable, remove from the Adaptation any credit as required by + Section 4(c), as requested. + b. You may Distribute or Publicly Perform an Adaptation only under the + terms of: (i) this License; (ii) a later version of this License with + the same License Elements as this License; (iii) a Creative Commons + jurisdiction license (either this or a later license version) that + contains the same License Elements as this License (e.g., + Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible + License. If you license the Adaptation under one of the licenses + mentioned in (iv), you must comply with the terms of that license. If + you license the Adaptation under the terms of any of the licenses + mentioned in (i), (ii) or (iii) (the "Applicable License"), you must + comply with the terms of the Applicable License generally and the + following provisions: (I) You must include a copy of, or the URI for, + the Applicable License with every copy of each Adaptation You + Distribute or Publicly Perform; (II) You may not offer or impose any + terms on the Adaptation that restrict the terms of the Applicable + License or the ability of the recipient of the Adaptation to exercise + the rights granted to that recipient under the terms of the Applicable + License; (III) You must keep intact all notices that refer to the + Applicable License and to the disclaimer of warranties with every copy + of the Work as included in the Adaptation You Distribute or Publicly + Perform; (IV) when You Distribute or Publicly Perform the Adaptation, + You may not impose any effective technological measures on the + Adaptation that restrict the ability of a recipient of the Adaptation + from You to exercise the rights granted to that recipient under the + terms of the Applicable License. This Section 4(b) applies to the + Adaptation as incorporated in a Collection, but this does not require + the Collection apart from the Adaptation itself to be made subject to + the terms of the Applicable License. + c. If You Distribute, or Publicly Perform the Work or any Adaptations or + Collections, You must, unless a request has been made pursuant to + Section 4(a), keep intact all copyright notices for the Work and + provide, reasonable to the medium or means You are utilizing: (i) the + name of the Original Author (or pseudonym, if applicable) if supplied, + and/or if the Original Author and/or Licensor designate another party + or parties (e.g., a sponsor institute, publishing entity, journal) for + attribution ("Attribution Parties") in Licensor's copyright notice, + terms of service or by other reasonable means, the name of such party + or parties; (ii) the title of the Work if supplied; (iii) to the + extent reasonably practicable, the URI, if any, that Licensor + specifies to be associated with the Work, unless such URI does not + refer to the copyright notice or licensing information for the Work; + and (iv) , consistent with Ssection 3(b), in the case of an + Adaptation, a credit identifying the use of the Work in the Adaptation + (e.g., "French translation of the Work by Original Author," or + "Screenplay based on original Work by Original Author"). The credit + required by this Section 4(c) may be implemented in any reasonable + manner; provided, however, that in the case of a Adaptation or + Collection, at a minimum such credit will appear, if a credit for all + contributing authors of the Adaptation or Collection appears, then as + part of these credits and in a manner at least as prominent as the + credits for the other contributing authors. For the avoidance of + doubt, You may only use the credit required by this Section for the + purpose of attribution in the manner set out above and, by exercising + Your rights under this License, You may not implicitly or explicitly + assert or imply any connection with, sponsorship or endorsement by the + Original Author, Licensor and/or Attribution Parties, as appropriate, + of You or Your use of the Work, without the separate, express prior + written permission of the Original Author, Licensor and/or Attribution + Parties. + d. Except as otherwise agreed in writing by the Licensor or as may be + otherwise permitted by applicable law, if You Reproduce, Distribute or + Publicly Perform the Work either by itself or as part of any + Adaptations or Collections, You must not distort, mutilate, modify or + take other derogatory action in relation to the Work which would be + prejudicial to the Original Author's honor or reputation. Licensor + agrees that in those jurisdictions (e.g. Japan), in which any exercise + of the right granted in Section 3(b) of this License (the right to + make Adaptations) would be deemed to be a distortion, mutilation, + modification or other derogatory action prejudicial to the Original + Author's honor and reputation, the Licensor will waive or not assert, + as appropriate, this Section, to the fullest extent permitted by the + applicable national law, to enable You to reasonably exercise Your + right under Section 3(b) of this License (right to make Adaptations) + but not otherwise. + +5. Representations, Warranties and Disclaimer + +UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR +OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY +KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, +INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, +FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF +LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, +WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION +OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. + +6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE +LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR +ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES +ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS +BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. Termination + + a. This License and the rights granted hereunder will terminate + automatically upon any breach by You of the terms of this License. + Individuals or entities who have received Adaptations or Collections + from You under this License, however, will not have their licenses + terminated provided such individuals or entities remain in full + compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will + survive any termination of this License. + b. Subject to the above terms and conditions, the license granted here is + perpetual (for the duration of the applicable copyright in the Work). + Notwithstanding the above, Licensor reserves the right to release the + Work under different license terms or to stop distributing the Work at + any time; provided, however that any such election will not serve to + withdraw this License (or any other license that has been, or is + required to be, granted under the terms of this License), and this + License will continue in full force and effect unless terminated as + stated above. + +8. Miscellaneous + + a. Each time You Distribute or Publicly Perform the Work or a Collection, + the Licensor offers to the recipient a license to the Work on the same + terms and conditions as the license granted to You under this License. + b. Each time You Distribute or Publicly Perform an Adaptation, Licensor + offers to the recipient a license to the original Work on the same + terms and conditions as the license granted to You under this License. + c. If any provision of this License is invalid or unenforceable under + applicable law, it shall not affect the validity or enforceability of + the remainder of the terms of this License, and without further action + by the parties to this agreement, such provision shall be reformed to + the minimum extent necessary to make such provision valid and + enforceable. + d. No term or provision of this License shall be deemed waived and no + breach consented to unless such waiver or consent shall be in writing + and signed by the party to be charged with such waiver or consent. + e. This License constitutes the entire agreement between the parties with + respect to the Work licensed here. There are no understandings, + agreements or representations with respect to the Work not specified + here. Licensor shall not be bound by any additional provisions that + may appear in any communication from You. This License may not be + modified without the mutual written agreement of the Licensor and You. + f. The rights granted under, and the subject matter referenced, in this + License were drafted utilizing the terminology of the Berne Convention + for the Protection of Literary and Artistic Works (as amended on + September 28, 1979), the Rome Convention of 1961, the WIPO Copyright + Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 + and the Universal Copyright Convention (as revised on July 24, 1971). + These rights and subject matter take effect in the relevant + jurisdiction in which the License terms are sought to be enforced + according to the corresponding provisions of the implementation of + those treaty provisions in the applicable national law. If the + standard suite of rights granted under applicable copyright law + includes additional rights not granted under this License, such + additional rights are deemed to be included in the License; this + License is not intended to restrict the license of any rights under + applicable law. + + +Creative Commons Notice + + Creative Commons is not a party to this License, and makes no warranty + whatsoever in connection with the Work. Creative Commons will not be + liable to You or any party on any legal theory for any damages + whatsoever, including without limitation any general, special, + incidental or consequential damages arising in connection to this + license. Notwithstanding the foregoing two (2) sentences, if Creative + Commons has expressly identified itself as the Licensor hereunder, it + shall have all rights and obligations of Licensor. + + Except for the limited purpose of indicating to the public that the + Work is licensed under the CCPL, Creative Commons does not authorize + the use by either party of the trademark "Creative Commons" or any + related trademark or logo of Creative Commons without the prior + written consent of Creative Commons. Any permitted use will be in + compliance with Creative Commons' then-current trademark usage + guidelines, as may be published on its website or otherwise made + available upon request from time to time. For the avoidance of doubt, + this trademark restriction does not form part of the License. + + Creative Commons may be contacted at https://creativecommons.org/. -- cgit v1.2.3 From 921aa02cc5162fae66bcc80026cb08d6938f60ed Mon Sep 17 00:00:00 2001 From: Darlington Nnam Date: Sun, 29 Jan 2023 23:39:36 +0100 Subject: added syntax highlighting, shortened lines --- cairo.html.markdown | 567 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 375 insertions(+), 192 deletions(-) diff --git a/cairo.html.markdown b/cairo.html.markdown index 25ef91aa..f106860a 100644 --- a/cairo.html.markdown +++ b/cairo.html.markdown @@ -6,160 +6,233 @@ contributors: --- # Cairo -Cairo is StarkNet's native language and the first Turing-complete language for scripting provable programs (where one party can prove to another that a certain computation was executed correctly) for general computations. + +Cairo is a Turing-complete language that allows you write provable programs +(where one party can prove to another that a certain computation + was executed correctly) on StarkNet. + # StarkNet -StarkNet is a decentralized ZK-rollup that operates as an Ethereum layer 2 chain. StarkNet enables Decentralized applications to achieve unlimited scale for their computation - without compromising Ethereum's decentralization and security, thereby solving the Scalability Trilemma. -In this document, we are going to be going in-depth into understanding Cairo's syntax and how you could create and deploy a Cairo smart contract on StarkNet. +StarkNet is a decentralized ZK-rollup that operates as an Ethereum layer 2 +chain. + +In this document, we are going to be going in-depth into understanding Cairo's +syntax and how you could create and deploy a Cairo smart contract on StarkNet. -**NB: As at the time of this writing, StarkNet is still at v0.10.3, with Cairo 1.0 coming soon. The ecosystem is young and evolving very fast, so you might want to check the [official docs](https://www.cairo-lang.org/docs) to confirm this document is still up-to-date. Pull requests are welcome!** +**NB: As at the time of this writing, StarkNet is still at v0.10.3, with Cairo +1.0 coming soon. The ecosystem is young and evolving very fast, so you might +want to check the [official docs](https://www.cairo-lang.org/docs) to confirm +this document is still up-to-date. Pull requests are welcome!** # Setting Up A Development Environment -Before we get started writing codes, we will need to setup a Cairo development environment, for writing, compiling and deploying our contracts to StarkNet. -For the purpose of this tutorial we are going to be using the [Protostar Framework](https://github.com/software-mansion/protostar). Installation steps can be found in the docs [here](https://docs.swmansion.com/protostar/docs/tutorials/installation). -Note that Protostar supports just Mac and Linux OS, Windows users might need to use WSL, or go for other alternatives such as the Official [StarkNet CLI](https://www.cairo-lang.org/docs/quickstart.html) or [Nile from Openzeppelin](https://github.com/OpenZeppelin/nile) -Once you're done with the installations, run the command `protostar -v` to confirm your installation was successful. If successful, you should see your Protostar version displayed on the screen. +Before we get started writing codes, we will need to setup a Cairo development +environment, for writing, compiling and deploying our contracts to StarkNet. +For the purpose of this tutorial we are going to be using the +[Protostar Framework](https://github.com/software-mansion/protostar). +Installation steps can be found in the docs +[here](https://docs.swmansion.com/protostar/docs/tutorials/installation). +Note that Protostar supports just Mac and Linux OS, Windows users might need to +use WSL, or go for other alternatives such as the Official +[StarkNet CLI](https://www.cairo-lang.org/docs/quickstart.html) or +[Nile from Openzeppelin](https://github.com/OpenZeppelin/nile) + +Once you're done with the installations, run the command `protostar -v` to +confirm your installation was successful. If successful, you should see your +Protostar version displayed on the screen. ## Initializing a new project -Protostar similar to Truffle for solidity development can be installed once and used for multiple projects. + +Protostar similar to Truffle for solidity development can be installed once and +used for multiple projects. To initialize a new Protostar project, run the following command: + ``` protostar init ``` -2. It would then request the project's name and the library's directory name, you'd need to fill in this, and a new project will be initialized successfully. +2. It would then request the project's name and the library's directory name, + you'd need to fill in this, and a new project will be initialized + successfully. # Compiling, Declaring, Deploying And Interacting With StarkNet Contracts -For the purpose of this tutorial, head over to this [github repo](https://github.com/Darlington02/CairoLearnXinYminutes) and clone locally. - -Within the `src` folder you'll find a boilerplate contract that comes with initializing a new Protostar project, `main.cairo`. We are going to be compiling, declaring and deploying this contract. +Within the `src` folder you'll find a boilerplate contract that comes with +initializing a new Protostar project, `main.cairo`. We are going to be +compiling, declaring and deploying this contract. ## Compiling Contracts -To compile a Cairo contract using Protostar, ensure a path to the contract is specified in the `[contracts]` section of the `protostar.toml` file. Once you've done that, open your terminal and run the command: + +To compile a Cairo contract using Protostar, ensure a path to the contract is +specified in the `[contracts]` section of the `protostar.toml` file. Once +you've done that, open your terminal and run the command: + ``` protostar build ``` -And you should get an output similar to what you see below, with a `main.json` and `main_abi.json` files created in the `build` folder. + +And you should get an output similar to what you see below, with a `main.json` +and `main_abi.json` files created in the `build` folder. building your contract ## Declaring Contracts -With the recent StarkNet update to 0.10.3, the DEPLOY transaction was deprecated and no longer works. To deploy a transaction, you must first declare a Contract to obtain the class hash, then deploy the declared contract using the [Universal Deployer Contract](https://community.starknet.io/t/universal-deployer-contract-proposal/1864). -Before declaring or deploying your contract using Protostar, you should set the private key associated with the specified account address in a file, or in the terminal. To set your private key in the terminal, run the command: +With the recent StarkNet update to 0.10.3, the DEPLOY transaction was +deprecated and no longer works. To deploy a transaction, you must first declare +a Contract to obtain the class hash, then deploy the declared contract using +the +[Universal Deployer Contract](https://community.starknet.io/t/universal-deployer-contract-proposal/1864). + +Before declaring or deploying your contract using Protostar, you should set the +private key associated with the specified account address in a file, or in the +terminal. To set your private key in the terminal, run the command: ``` export PROTOSTAR_ACCOUNT_PRIVATE_KEY=[YOUR PRIVATE KEY HERE] ``` Then to declare our contract using Protostar run the following command: + ``` -protostar declare ./build/main.json --network testnet --account 0x0691622bBFD29e835bA4004e7425A4e9630840EbD11c5269DE51C16774585b16 --max-fee auto +protostar declare ./build/main.json --network testnet --account +0x0691622bBFD29e835bA4004e7425A4e9630840EbD11c5269DE51C16774585b16 --max-fee +auto ``` -where `network` specifies the network we are deploying to, `account` specifies account whose private key we are using, `max-fee` specifies the maximum fee to be paid for the transaction. You should get the class hash outputted as seen below: +where `network` specifies the network we are deploying to, `account` specifies +account whose private key we are using, `max-fee` specifies the maximum fee to +be paid for the transaction. You should get the class hash outputted as seen +below: declaring your contract ## Deploying Contracts -After obtaining our class hash from declaring, we can now deploy using the below command: + +After obtaining our class hash from declaring, we can now deploy using the +below command: + ``` -protostar deploy 0x02a5de1b145e18dfeb31c7cd7ff403714ededf5f3fdf75f8b0ac96f2017541bc --network testnet --account 0x0691622bBFD29e835bA4004e7425A4e9630840EbD11c5269DE51C16774585b16 --max-fee auto +protostar deploy +0x02a5de1b145e18dfeb31c7cd7ff403714ededf5f3fdf75f8b0ac96f2017541bc --network +testnet --account +0x0691622bBFD29e835bA4004e7425A4e9630840EbD11c5269DE51C16774585b16 --max-fee +auto ``` -where `0x02a5de1b145e18dfeb31c7cd7ff403714ededf5f3fdf75f8b0ac96f2017541bc` is the class hash of our contract. +where `0x02a5de1b145e18dfeb31c7cd7ff403714ededf5f3fdf75f8b0ac96f2017541bc` is +the class hash of our contract. deploying your contract ## Interacting With Contracts -To interact with your deployed contract, we will be using Argent X (alternative - Braavos), and Starkscan (alternative - Voyager). To install and setup Argent X, check out this [guide](https://www.argent.xyz/learn/how-to-create-an-argent-x-wallet/). -Copy your contract address, displayed on screen from the previous step, and head over to [Starkscan](https://testnet.starkscan.co/) to search for the contract. Once found, you can make write calls to the contract by following the steps below: +To interact with your deployed contract, we will be using Argent X +(alternative - Braavos), and Starkscan (alternative - Voyager). To install and +setup Argent X, check out this +[guide](https://www.argent.xyz/learn/how-to-create-an-argent-x-wallet/). + +Copy your contract address, displayed on screen from the previous step, and +head over to [Starkscan](https://testnet.starkscan.co/) to search for the +contract. Once found, you can make write calls to the contract by following the +steps below: + 1. Click on the "connect wallet" button -connect wallet + connect wallet 2. Select Argent X and approve the connection -connect to argentX + connect to argentX 3. You can now make read and write calls easily. # Let's learn Cairo -First let's look at a default contract that comes with Protostar -``` - // Allows you to set balanace on deployment, increase, and get the balance. - - // Language directive - instructs compiler its a StarkNet contract - %lang starknet - - // Library imports from the Cairo-lang library - from starkware.cairo.common.math import assert_nn - from starkware.cairo.common.cairo_builtins import HashBuiltin - - // @dev Storage variable that stores the balance of a user. - // @storage_var is a decorator that instructs the compiler the function below it is a storage variable. - @storage_var - func balance() -> (res: felt) { - } - - // @dev Constructor writes the balance variable to 0 on deployment - // Constructors sets storage variables on deployment. Can accept arguments too. - @constructor - func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { - balance.write(0); - return (); - } - // @dev increase_balance updates the balance variable - // @param amount the amount you want to add to balance - // @external is a decorator that specifies the func below it is an external function. - @external - func increase_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - amount: felt - ) { - with_attr error_message("Amount must be positive. Got: {amount}.") { - assert_nn(amount); - } +First let's look at a default contract that comes with Protostar - let (res) = balance.read(); - balance.write(res + amount); - return (); +```cairo +// Allows you to set balance on deployment, increase, and get the balance. + +// Language directive - instructs compiler its a StarkNet contract +%lang starknet + +// Library imports from the Cairo-lang library +from starkware.cairo.common.math import assert_nn +from starkware.cairo.common.cairo_builtins import HashBuiltin + +// @dev Storage variable that stores the balance of a user. +// @storage_var is a decorator that instructs the compiler the function +// below it is a storage variable. +@storage_var +func balance() -> (res: felt) { +} + +// @dev Constructor writes the balance variable to 0 on deployment +// Constructors sets storage variables on deployment. Can accept arguments too. +@constructor +func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}() {balance.write(0); return (); +} + +// @dev increase_balance updates the balance variable +// @param amount the amount you want to add to balance +// @external is a decorator that specifies the func below it is an external +// function. +@external +func increase_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}(amount: felt){ + with_attr error_message("Amount must be positive. Got: {amount}.") { + assert_nn(amount); } - // @dev returns the balance variable - // @view is a decorator that specifies the func below it is a view function. - @view - func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (res: felt) { - let (res) = balance.read(); - return (res,); - } + let (res) = balance.read(); + balance.write(res + amount); + return (); +} - // before proceeding, try to build, deploy and interact with this contract! - // NB: Should be at main.cairo if you are using Protostar. +// @dev returns the balance variable +// @view is a decorator that specifies the func below it is a view function. +@view +func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}() -> (res: felt) { + let (res) = balance.read(); + return (res,); +} +// before proceeding, try to build, deploy and interact with this contract! +// NB: Should be at main.cairo if you are using Protostar. ``` + Now unto the main lessons ### 1. THE FELT DATA TYPE -``` - // Unlike solidity, where you have access to various data types, Cairo comes with just a single data type..felts - // Felts stands for Field elements, and are a 252 bit integer in the range 0<=x<=P where P is a prime number. - // You can create a Uint256 in Cairo by utlizing a struct of two 128 bits felts. + +```cairo + // Unlike solidity, where you have access to various data types, Cairo + // comes with just a single data type..felts + // Felts stands for Field elements, and are a 252 bit integer in the range + // 0<=x<=P where P is a prime number. + // You can create a Uint256 in Cairo by utlizing a struct of two 128 bits + // felts. struct Uint256 { low: felt, // The low 128 bits of the value. high: felt, // The high 128 bits of the value. } - // To avoid running into issues with divisions, it's safer to work with the unsigned_div_rem method from Cairo-lang's library. + // To avoid running into issues with divisions, it's safer to work with the + // unsigned_div_rem method from Cairo-lang's library. ``` ### 2. LANG DIRECTIVE AND IMPORTS -``` - // To get started with writing a StarkNet contract, you must specify the directive: + +```cairo + // To get started with writing a StarkNet contract, you must specify the + // directive: %lang starknet - // This directive informs the compiler you are writing a contract and not a program. - // The difference between both is contracts have access to StarkNet's storage, programs don't and as such are stateless. + // This directive informs the compiler you are writing a contract and not a + // program. + // The difference between both is contracts have access to StarkNet's + // storage, programs don't and as such are stateless. + + // There are important functions you might need to import from the official + // Cairo-lang library or Openzeppelin's. e.g. - // There are important functions you might need to import from the official Cairo-lang library or Openzeppelin's. e.g. - from starkware.cairo.common.cairo_builtins import HashBuiltin from cairo_contracts.src.openzeppelin.token.erc20.library import ERC20 from starkware.cairo.common.uint256 import Uint256 @@ -167,9 +240,11 @@ Now unto the main lessons ``` ### 3. DATA STRUCTURES -``` + +```cairo // A. STORAGE VARIABLES - // Cairo's storage is a map with 2^251 slots, where each slot is a felt which is initialized to 0. + // Cairo's storage is a map with 2^251 slots, where each slot is a felt + // which is initialized to 0. // You create one using the @storage_var decorator @storage_var @@ -177,7 +252,8 @@ Now unto the main lessons } // B. STORAGE MAPPINGS - // Unlike soldity where mappings have a separate keyword, in Cairo you create mappings using storage variables. + // Unlike soldity where mappings have a separate keyword, in Cairo you + // create mappings using storage variables. @storage_var func names(address: felt) -> (name: felt){ @@ -185,7 +261,8 @@ Now unto the main lessons // C. STRUCTS // Structs are a means to create custom data types in Cairo. - // A Struct has a size, which is the sum of the sizes of its members. The size can be retrieved using MyStruct.SIZE. + // A Struct has a size, which is the sum of the sizes of its members. The + // size can be retrieved using MyStruct.SIZE. // You create a struct in Cairo using the `struct` keyword. struct Person { @@ -200,20 +277,25 @@ Now unto the main lessons // To create a constant in Cairo, you use the `const` keyword. // Its proper practice to capitalize constant names. - const USER = 0x01C6cfC1DB2ae90dACEA243F0a8C2F4e32560F7cDD398e4dA2Cc56B733774E9b + const USER = +0x01C6cfC1DB2ae90dACEA243F0a8C2F4e32560F7cDD398e4dA2Cc56B733774E9b // E. ARRAYS - // Arrays can be defined as a pointer(felt*) to the first element of the array. + // Arrays can be defined as a pointer(felt*) to the first element of the + //array. // As an array is populated, its elements take up contigous memory cells. - // The `alloc` keyword can be used to dynamically allocate a new memory segment, which can be used to store an array + // The `alloc` keyword can be used to dynamically allocate a new memory + // segment, which can be used to store an array let (myArray: felt*) = alloc (); assert myArray[0] = 1; assert myArray[1] = 2; assert myArray[3] = 3; - // You can also use the `new` operator to create fixed-size arrays using tuples - // The new operator is useful as it enables you allocate memory and initialize the object in one instruction + // You can also use the `new` operator to create fixed-size arrays using + //tuples + // The new operator is useful as it enables you allocate memory and + // initialize the object in one instruction func foo() { tempvar arr: felt* = new (1, 1, 2, 3, 5); @@ -223,13 +305,15 @@ Now unto the main lessons // F. TUPLES // A tuple is a finite, ordered, unchangeable list of elements - // It is represented as a comma-separated list of elements enclosed by parentheses + // It is represented as a comma-separated list of elements enclosed by + // parentheses // Their elements may be of any combination of valid types. local tuple0: (felt, felt, felt) = (7, 9, 13); // G. EVENTS - // Events allows a contract emit information during the course of its execution, that can be used outside of StarkNet. + // Events allows a contract emit information during the course of its + // execution, that can be used outside of StarkNet. // To create an event: @event @@ -242,24 +326,28 @@ Now unto the main lessons ``` ### 4. CONSTRUCTORS, EXTERNAL AND VIEW FUNCTIONS -``` + +```cairo // A. CONSTRUCTORS - // Constructors are a way to intialize state variables on contract deployment + // Constructors are a way to intialize state variables on contract + // deployment // You create a constructor using the @constructor decorator @constructor - func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(_name: felt) { + func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}(_name: felt) { let (caller) = get_caller_address(); names.write(caller, _name); return (); } - + // B. EXTERNAL FUNCTIONS // External functions are functions that modifies the state of the network // You create an external function using the @external decorator @external - func store_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(_name: felt){ + func store_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}(_name: felt){ let (caller) = get_caller_address(); names.write(caller, _name); stored_name.emit(caller, _name); @@ -271,61 +359,84 @@ Now unto the main lessons // You can create a view function using the @view decorator @view - func get_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(_address: felt) -> (name: felt){ + func get_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}(_address: felt) -> (name: felt){ let (name) = names.read(_address); return (name,); } - // NB: Unlike Solidity, Cairo supports just External and View function types. - // You can alternatively also create an internal function by not adding any decorator to the function. + // NB: Unlike Solidity, Cairo supports just External and View function + // types. + // You can alternatively also create an internal function by not adding any + // decorator to the function. ``` ### 5. DECORATORS -``` - // All functions in Cairo are specified by the `func` keyword, which can be confusing. - // Decorators are used by the compiler to distinguish between these functions. + +```cairo + // All functions in Cairo are specified by the `func` keyword, which can be + // confusing. + // Decorators are used by the compiler to distinguish between these + // functions. // Here are the most common decorators you'll encounter in Cairo: // 1. @storage_var — used for specifying state variables. // 2. @constructor — used for specifying constructors. - // 3. @external — used for specifying functions that write to a state variable. + // 3. @external — used for specifying functions that write to a state + // variable. // 4. @event — used for specifying events - // 5. @view — used for specifying functions that reads from a state variable. + // 5. @view — used for specifying functions that reads from a state + // variable. // 6. @contract_interface - used for specifying function interfaces. - // 7. @l1_handler — used for specifying functions that processes message sent from an L1 contract in a messaging bridge. + // 7. @l1_handler — used for specifying functions that processes message + // sent from an L1 contract in a messaging bridge. ``` ### 6. BUILTINS, HINTS & IMPLICIT ARGUMENTS -``` + +```cairo // A. BUILTINS - // Builtins are predefined optimized low-level execution units, which are added to Cairo’s CPU board. - // They help perform predefined computations like pedersen hashing, bitwise operations etc, which are expensive to perform in Vanilla Cairo. - // Each builtin in Cairo, is assigned a separate memory location, accessible through regular Cairo memory calls using implicit parameters. + // Builtins are predefined optimized low-level execution units, which are + // added to Cairo’s CPU board. + // They help perform predefined computations like pedersen hashing, bitwise + // operations etc, which are expensive to perform in Vanilla Cairo. + // Each builtin in Cairo, is assigned a separate memory location, + // accessible through regular Cairo memory calls using implicit parameters. // You specify them using the %builtins directive // Here is a list of available builtins in Cairo: // 1. output — the output builtin is used for writing program outputs - // 2. pedersen — the pedersen builtin is used for pedersen hashing computations - // 3. range_check — This builtin is mostly used for integer comparisons, and facilitates check to confirm that a field element is within a range [0, 2^128) + // 2. pedersen — the pedersen builtin is used for pedersen hashing + // computations + // 3. range_check — This builtin is mostly used for integer comparisons, + // and facilitates check to confirm that a field element is within a range [0, + // 2^128) // 4. ecdsa — the ecdsa builtin is used for verifying ECDSA signatures - // 5. bitwise — the bitwise builtin is used for carrying out bitwise operations on felts + // 5. bitwise — the bitwise builtin is used for carrying out bitwise + // operations on felts // B. HINTS - // Hints are pieces of Python codes, which contains instructions that only the prover sees and executes + // Hints are pieces of Python codes, which contains instructions that only + // the prover sees and executes // From the point of view of the verifier these hints do not exist // To specify a hint in Cairo, you need to encapsulate it within %{ and%} - // Its good practice to avoid using hints as much as you can in your contracts, as hints are not added to the bytecode, and thus do not count in the total number of execution steps. + // Its good practice to avoid using hints as much as you can in your + // contracts, as hints are not added to the bytecode, and thus do not count in the + // total number of execution steps. - %{ - # Python hint goes here + %{ + # Python hint goes here %} // C. IMPLICIT ARGUMENTS - // Implicit arguments are not restricted to the function body, but can be inherited by other functions calls that require them. - // Implicit arguments are passed in between curly bracelets, like you can see below: + // Implicit arguments are not restricted to the function body, but can be + // inherited by other functions calls that require them. + // Implicit arguments are passed in between curly bracelets, like you can + // see below: - func store_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(_name: felt){ + func store_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}(_name: felt){ let (caller) = get_caller_address(); names.write(caller, _name); stored_name.emit(caller, _name); @@ -334,16 +445,20 @@ Now unto the main lessons ``` ### 7. ERROR MESSAGES & ACCESS CONTROLS -``` - // You can create custom errors in Cairo which is outputted to the user upon failed execution. - // This can be very useful for implementing checks and proper access control mechanisms. + +```cairo + // You can create custom errors in Cairo which is outputted to the user + // upon failed execution. + // This can be very useful for implementing checks and proper access + // control mechanisms. // An example is preventing a user to call a function except user is admin. // imports from starkware.starknet.common.syscalls import get_caller_address // create an admin constant - const ADMIN = 0x01C6cfC1DB2ae90dACEA243F0a8C2F4e32560F7cDD398e4dA2Cc56B733774E9b + const ADMIN = +0x01C6cfC1DB2ae90dACEA243F0a8C2F4e32560F7cDD398e4dA2Cc56B733774E9b // implement access control with_attr error_message("You do not have access to make this action!"){ @@ -351,12 +466,15 @@ Now unto the main lessons assert ADMIN = caller; } - // using an assert statement throws if condition is not true, thus returning the specified error. + // using an assert statement throws if condition is not true, thus + // returning the specified error. ``` ### 8. CONTRACT INTERFACES -``` - // Contract interfaces provide a means for one contract to invoke or call the external function of another contract. + +```cairo + // Contract interfaces provide a means for one contract to invoke or call + // the external function of another contract. // To create a contract interface, you use the @contract_interface keyword @contract_interface @@ -368,22 +486,29 @@ Now unto the main lessons } } - // Once a contract interface is specified, any contract can make calls to that contract passing in the contract address as the first parameter like this: + // Once a contract interface is specified, any contract can make calls to + // that contract passing in the contract address as the first parameter like this: IENS.store_name(contract_address, _name); - // Note that Interfaces excludes the function body/logic and the implicit arguments. + // Note that Interfaces excludes the function body/logic and the implicit + // arguments. ``` ### 9. RECURSIONS -``` - // Due to the unavailability of loops, Recursions are the go-to for similar operations. - // In simple terms, a recursive function is one which calls itself repeatedly. - // A good example to demonstrate this is writing a function for getting the nth fibonacci number: +```cairo + // Due to the unavailability of loops, Recursions are the go-to for similar + // operations. + // In simple terms, a recursive function is one which calls itself + // repeatedly. + + // A good example to demonstrate this is writing a function for getting the + // nth fibonacci number: @external - func fibonacci{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(n : felt) -> (result : felt){ + func fibonacci{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}(n : felt) -> (result : felt){ alloc_locals; if (n == 0){ return (0); @@ -396,48 +521,67 @@ Now unto the main lessons return (result=(x + y)); } - // The nth fibonacci term is the sum of the nth - 1 and the nth - 2 numbers, that's why we get these two as (x, y) using recursion. - // NB: when implementing recursive functions, always remember to implement a base case (n==0, n==1 in our case), to prevent stack overflow. + // The nth fibonacci term is the sum of the nth - 1 and the nth - 2 + // numbers, that's why we get these two as (x, y) using recursion. + // NB: when implementing recursive functions, always remember to implement + // a base case (n==0, n==1 in our case), to prevent stack overflow. ``` Some low-level stuffs ### 10. REGISTERS -``` + +```cairo // Registers holds values that may change over time. // There are 3 major types of Registers: - // 1. ap (allocation pointer) points to a yet unused memory. Temporary variables created using `let`, `tempvar` are held here, and thus susceptible to being revoked - // 2. fp (frame pointer) points to the frame of the current function. The address of all the function arguments and local variables are relative to this register and as such can never be revoked + // 1. ap (allocation pointer) points to a yet unused memory. Temporary + // variables created using `let`, `tempvar` are held here, and thus susceptible to + // being revoked + // 2. fp (frame pointer) points to the frame of the current function. The + // address of all the function arguments and local variables are relative to this + // register and as such can never be revoked // 3. pc (program counter) points to the current instruction ``` ### 11. REVOKED REFERENCES -``` - // Revoked references occurs when there is a call instruction to another function, between the definition of a reference variable that depends on `ap`(temp variables) and its usage. This occurs as the compiler may not be able to compute the change of `ap` (as one may jump to the label from another place in the program, or call a function that might change ap in an unknown way). + +```cairo + // Revoked references occurs when there is a call instruction to another + // function, between the definition of a reference variable that depends on + // `ap`(temp variables) and its usage. This occurs as the compiler may not be able + // to compute the change of `ap` (as one may jump to the label from another place + // in the program, or call a function that might change ap in an unknown way). // Here is an example to demonstrate what I mean: @external - func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (res: felt) { + func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}() -> (res: felt) { return (res=100); } @external - func double_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (res: felt) { + func double_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}() -> (res: felt) { let multiplier = 2; let (balance) = get_balance(); let new_balance = balance * multiplier; return (res=new_balance); } - - // If you run that code, you'll run into the revoked reference error as we are trying to access the `multiplier` variable after calling the get_balance function; - // To solve revoked references, In simple cases you can resolve this issue, by adding the keyword, `alloc_locals` within function scopes, but in most complex cases you might need to create a local variable to resolve it. + // If you run that code, you'll run into the revoked reference error as we + // are trying to access the `multiplier` variable after calling the get_balance + // function; + + // To solve revoked references, In simple cases you can resolve this issue, + // by adding the keyword, `alloc_locals` within function scopes, but in most + // complex cases you might need to create a local variable to resolve it. // resolving the `double_balance` function: @external - func double_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (res: felt) { + func double_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}() -> (res: felt) { alloc_locals; let multiplier = 2; let (balance) = get_balance(); @@ -449,38 +593,51 @@ Some low-level stuffs Miscellaneous ### 12. Understanding Cairo's punctuations -``` + +```cairo // ; (semicolon). Used at the end of each instruction - // ( ) (parentheses). Used in a function declaration, if statements, and in a tuple declaration + // ( ) (parentheses). Used in a function declaration, if statements, and in + // a tuple declaration - // { } (curly brackets). Used in a declaration of implicit arguments and to define code blocks. + // { } (curly brackets). Used in a declaration of implicit arguments and to + // define code blocks. - // [ ] (square brackets). Standalone brackets represent the value at a particular address location (such as the allocation pointer, [ap]). Brackets following a pointer or a tuple act as a subscript operator, where x[2] represents the element with index 2 in x. + // [ ] (square brackets). Standalone brackets represent the value at a + // particular address location (such as the allocation pointer, [ap]). Brackets + // following a pointer or a tuple act as a subscript operator, where x[2] + // represents the element with index 2 in x. // * Single asterisk. Refers to the pointer of an expression. - // % Percent sign. Appears at the start of a directive, such as %builtins or %lang. + // % Percent sign. Appears at the start of a directive, such as %builtins + // or %lang. // %{ %} Represents Python hints. - // _ (underscore). A placeholder to handle values that are not used, such as an unused function return value. + // _ (underscore). A placeholder to handle values that are not used, such + // as an unused function return value. ``` # FULL CONTRACT EXAMPLE -Below is a simple automated market maker contract example that implements most of what we just learnt! Re-write, deploy, have fun! -``` + +Below is a simple automated market maker contract example that implements most +of what we just learnt! Re-write, deploy, have fun! + +```cairo %lang starknet from starkware.cairo.common.cairo_builtins import HashBuiltin from starkware.cairo.common.hash import hash2 from starkware.cairo.common.alloc import alloc - from starkware.cairo.common.math import (assert_le, assert_nn_le, unsigned_div_rem) - from starkware.starknet.common.syscalls import (get_caller_address, storage_read, storage_write) + from starkware.cairo.common.math import (assert_le, assert_nn_le, + unsigned_div_rem) + from starkware.starknet.common.syscalls import (get_caller_address, + storage_read, storage_write) - // + // // CONSTANTS - // + // // @dev the maximum amount of each token that belongs to the AMM @@ -493,13 +650,13 @@ Below is a simple automated market maker contract example that implements most o const POOL_UPPER_BOUND = 2 ** 30; const ACCOUNT_BALANCE_BOUND = 1073741; // (2 ** 30 / 1000) - // + // // STORAGE VARIABLES - // + // // @dev A map from account and token type to corresponding balance @storage_var - func account_balance(account_id: felt, token_type: felt) -> (balance: felt) { + func account_balance(account_id: felt, token_type: felt) -> (balance: felt){ } // @dev a map from token type to corresponding pool balance @@ -507,15 +664,16 @@ Below is a simple automated market maker contract example that implements most o func pool_balance(token_type: felt) -> (balance: felt) { } - // + // // GETTERS - // + // // @dev returns account balance for a given token // @param account_id Account to be queried // @param token_type Token to be queried @view - func get_account_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + func get_account_token_balance{syscall_ptr: felt*, pedersen_ptr: + HashBuiltin*, range_check_ptr}( account_id: felt, token_type: felt ) -> (balance: felt) { return account_balance.read(account_id, token_type); @@ -524,21 +682,23 @@ Below is a simple automated market maker contract example that implements most o // @dev return the pool's balance // @param token_type Token type to get pool balance @view - func get_pool_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + func get_pool_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}( token_type: felt ) -> (balance: felt) { return pool_balance.read(token_type); } - // + // // EXTERNALS - // + // // @dev set pool balance for a given token // @param token_type Token whose balance is to be set // @param balance Amount to be set as balance @external - func set_pool_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + func set_pool_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}( token_type: felt, balance: felt ) { with_attr error_message("exceeds maximum allowed tokens!"){ @@ -553,14 +713,17 @@ Below is a simple automated market maker contract example that implements most o // @param token_a_amount amount of token a to be added // @param token_b_amount amount of token b to be added @external - func add_demo_token{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + func add_demo_token{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}( token_a_amount: felt, token_b_amount: felt ) { alloc_locals; let (account_id) = get_caller_address(); - modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_A, amount=token_a_amount); - modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_B, amount=token_b_amount); + modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_A, + amount=token_a_amount); + modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_B, + amount=token_b_amount); return (); } @@ -569,7 +732,8 @@ Below is a simple automated market maker contract example that implements most o // @param token_a amount of token a to be set in pool // @param token_b amount of token b to be set in pool @external - func init_pool{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + func init_pool{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}( token_a: felt, token_b: felt ) { with_attr error_message("exceeds maximum allowed tokens!"){ @@ -606,27 +770,30 @@ Below is a simple automated market maker contract example that implements most o } // check user has enough funds - let (account_from_balance) = get_account_token_balance(account_id=account_id, token_type=token_from); + let (account_from_balance) = + get_account_token_balance(account_id=account_id, token_type=token_from); with_attr error_message("insufficient balance!"){ assert_le(amount_from, account_from_balance); } let (token_to) = get_opposite_token(token_type=token_from); - let (amount_to) = do_swap(account_id=account_id, token_from=token_from, token_to=token_to, amount_from=amount_from); + let (amount_to) = do_swap(account_id=account_id, token_from=token_from, + token_to=token_to, amount_from=amount_from); return (amount_to=amount_to); } - // + // // INTERNALS - // + // // @dev internal function that updates account balance for a given token // @param account_id Account whose balance is to be modified // @param token_type Token type to be modified // @param amount Amount Amount to be added - func modify_account_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + func modify_account_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}( account_id: felt, token_type: felt, amount: felt ) { let (current_balance) = account_balance.read(account_id, token_type); @@ -636,34 +803,44 @@ Below is a simple automated market maker contract example that implements most o assert_nn_le(new_balance, BALANCE_UPPER_BOUND - 1); } - account_balance.write(account_id=account_id, token_type=token_type, value=new_balance); + account_balance.write(account_id=account_id, token_type=token_type, + value=new_balance); return (); } - // @dev internal function that swaps tokens between the given account and the pool + // @dev internal function that swaps tokens between the given account and + // the pool // @param account_id Account whose tokens are to be swapped // @param token_from Token type to be swapped from // @param token_to Token type to be swapped to // @param amount_from Amount to be swapped - func do_swap{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + func do_swap{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}( account_id: felt, token_from: felt, token_to: felt, amount_from: felt ) -> (amount_to: felt) { alloc_locals; // get pool balance - let (local amm_from_balance) = get_pool_token_balance(token_type = token_from); - let (local amm_to_balance) = get_pool_token_balance(token_type=token_to); + let (local amm_from_balance) = get_pool_token_balance(token_type = + token_from); + let (local amm_to_balance) = + get_pool_token_balance(token_type=token_to); // calculate swap amount - let (local amount_to, _) = unsigned_div_rem((amm_to_balance * amount_from), (amm_from_balance + amount_from)); + let (local amount_to, _) = unsigned_div_rem((amm_to_balance * + amount_from), (amm_from_balance + amount_from)); // update token_from balances - modify_account_balance(account_id=account_id, token_type=token_from, amount=-amount_from); - set_pool_token_balance(token_type=token_from, balance=(amm_from_balance + amount_from)); + modify_account_balance(account_id=account_id, token_type=token_from, + amount=-amount_from); + set_pool_token_balance(token_type=token_from, balance=(amm_from_balance + + amount_from)); // update token_to balances - modify_account_balance(account_id=account_id, token_type=token_to, amount=amount_to); - set_pool_token_balance(token_type=token_to, balance=(amm_to_balance - amount_to)); + modify_account_balance(account_id=account_id, token_type=token_to, + amount=amount_to); + set_pool_token_balance(token_type=token_to, balance=(amm_to_balance - + amount_to)); return (amount_to=amount_to); } @@ -680,6 +857,7 @@ Below is a simple automated market maker contract example that implements most o ``` # Additional Resources + 1. [Official documentation](https://www.cairo-lang.org/docs/) 2. [Starknet EDU](https://medium.com/starknet-edu) 3. [Journey through Cairo](https://medium.com/@darlingtonnnam/journey-through-cairo-i-setting-up-protostar-and-argentx-for-local-development-ba40ae6c5524) @@ -687,15 +865,18 @@ Below is a simple automated market maker contract example that implements most o 5. [Learn about StarkNet with Argent](https://www.argent.xyz/learn/tag/starknet/) # Development Frameworks + 1. [Protostar](https://docs.swmansion.com/protostar/docs/tutorials/installation) 2. [Nile](https://github.com/OpenZeppelin/nile) 3. [StarkNet CLI](https://www.cairo-lang.org/docs/quickstart.html) # Helpful Libraries + 1. [Cairo-lang](https://github.com/starkware-libs/cairo-lang) 2. [Openzeppelin](https://github.com/OpenZeppelin/cairo-contracts) # Educational Repos + 1. [StarkNet Cairo 101](https://github.com/starknet-edu/starknet-cairo-101) 2. [StarkNet ERC721](https://github.com/starknet-edu/starknet-erc721) 3. [StarkNet ERC20](https://github.com/starknet-edu/starknet-erc20) @@ -704,11 +885,13 @@ Below is a simple automated market maker contract example that implements most o 6. [StarkNet Accounts](https://github.com/starknet-edu/starknet-accounts) 7. [Min-Starknet](https://github.com/Darlington02/min-starknet) -# Security +# Security + 1. [Amarna static analysis for Cairo programs](https://blog.trailofbits.com/2022/04/20/amarna-static-analysis-for-cairo-programs/) 2. [Cairo and StarkNet security by Ctrl03](https://ctrlc03.github.io/) 3. [How to hack almost any Cairo smart contract](https://medium.com/ginger-security/how-to-hack-almost-any-starknet-cairo-smart-contract-67b4681ac0f6) 4. [Analyzing Cairo code using Armana](https://dic0de.substack.com/p/analyzing-cairo-code-using-amarna?sd=pf) # Future TO-DOs -Update tutorial to fit Cairo 1.0 \ No newline at end of file + +Update tutorial to fit Cairo 1.0 -- cgit v1.2.3 From 824fed572a1703b5130b8fbfce4b14fef28ede38 Mon Sep 17 00:00:00 2001 From: Darlington Nnam Date: Tue, 31 Jan 2023 21:49:44 +0100 Subject: Update cairo.html.markdown --- cairo.html.markdown | 1277 +++++++++++++++++++++++++-------------------------- 1 file changed, 621 insertions(+), 656 deletions(-) diff --git a/cairo.html.markdown b/cairo.html.markdown index f106860a..18ac81af 100644 --- a/cairo.html.markdown +++ b/cairo.html.markdown @@ -8,10 +8,10 @@ contributors: # Cairo Cairo is a Turing-complete language that allows you write provable programs -(where one party can prove to another that a certain computation - was executed correctly) on StarkNet. +(where one party can prove to another that a certain computation was executed +correctly) on StarkNet. -# StarkNet +## StarkNet StarkNet is a decentralized ZK-rollup that operates as an Ethereum layer 2 chain. @@ -24,7 +24,7 @@ syntax and how you could create and deploy a Cairo smart contract on StarkNet. want to check the [official docs](https://www.cairo-lang.org/docs) to confirm this document is still up-to-date. Pull requests are welcome!** -# Setting Up A Development Environment +## Setting Up A Development Environment Before we get started writing codes, we will need to setup a Cairo development environment, for writing, compiling and deploying our contracts to StarkNet. @@ -44,23 +44,23 @@ Protostar version displayed on the screen. ## Initializing a new project Protostar similar to Truffle for solidity development can be installed once and -used for multiple projects. -To initialize a new Protostar project, run the following command: +used for multiple projects. To initialize a new Protostar project, run the +following command: ``` protostar init ``` -2. It would then request the project's name and the library's directory name, - you'd need to fill in this, and a new project will be initialized - successfully. +It would then request the project's name and the library's directory name, +you'd need to fill in this, and a new project will be initialized successfully. + +## Compiling, Declaring, Deploying and Interacting with StarkNet Contracts -# Compiling, Declaring, Deploying And Interacting With StarkNet Contracts Within the `src` folder you'll find a boilerplate contract that comes with initializing a new Protostar project, `main.cairo`. We are going to be compiling, declaring and deploying this contract. -## Compiling Contracts +### Compiling Contracts To compile a Cairo contract using Protostar, ensure a path to the contract is specified in the `[contracts]` section of the `protostar.toml` file. Once @@ -74,12 +74,11 @@ And you should get an output similar to what you see below, with a `main.json` and `main_abi.json` files created in the `build` folder. building your contract -## Declaring Contracts +### Declaring Contracts With the recent StarkNet update to 0.10.3, the DEPLOY transaction was deprecated and no longer works. To deploy a transaction, you must first declare -a Contract to obtain the class hash, then deploy the declared contract using -the +a Contract to obtain the class hash, then deploy the declared contract using the [Universal Deployer Contract](https://community.starknet.io/t/universal-deployer-contract-proposal/1864). Before declaring or deploying your contract using Protostar, you should set the @@ -90,12 +89,14 @@ terminal. To set your private key in the terminal, run the command: export PROTOSTAR_ACCOUNT_PRIVATE_KEY=[YOUR PRIVATE KEY HERE] ``` -Then to declare our contract using Protostar run the following command: +Then to declare our contract using Protostar run the following command (for +visual clarity, the backslash sign symbolizes the continuing line): ``` -protostar declare ./build/main.json --network testnet --account -0x0691622bBFD29e835bA4004e7425A4e9630840EbD11c5269DE51C16774585b16 --max-fee -auto +protostar declare ./build/main.json \ + --network testnet \ + --account 0x0691622bBFD29e835bA4004e7425A4e9630840EbD11c5269DE51C16774585b16 \ + --max-fee auto ``` where `network` specifies the network we are deploying to, `account` specifies @@ -104,48 +105,47 @@ be paid for the transaction. You should get the class hash outputted as seen below: declaring your contract -## Deploying Contracts +### Deploying Contracts After obtaining our class hash from declaring, we can now deploy using the -below command: +command below: ``` -protostar deploy -0x02a5de1b145e18dfeb31c7cd7ff403714ededf5f3fdf75f8b0ac96f2017541bc --network -testnet --account -0x0691622bBFD29e835bA4004e7425A4e9630840EbD11c5269DE51C16774585b16 --max-fee -auto +protostar \ + deploy 0x02a5de1b145e18dfeb31c7cd7ff403714ededf5f3fdf75f8b0ac96f2017541bc \ + --network testnet \ + --account 0x0691622bBFD29e835bA4004e7425A4e9630840EbD11c5269DE51C16774585b16 \ + --max-fee auto ``` where `0x02a5de1b145e18dfeb31c7cd7ff403714ededf5f3fdf75f8b0ac96f2017541bc` is the class hash of our contract. deploying your contract -## Interacting With Contracts +### Interacting with Contracts -To interact with your deployed contract, we will be using Argent X -(alternative - Braavos), and Starkscan (alternative - Voyager). To install and -setup Argent X, check out this +To interact with your deployed contract, we will be using `Argent X` +(alternative: `Braavos`), and `Starkscan` (alternative: `Voyager`). To install +and setup `Argent X`, see this [guide](https://www.argent.xyz/learn/how-to-create-an-argent-x-wallet/). Copy your contract address, displayed on screen from the previous step, and head over to [Starkscan](https://testnet.starkscan.co/) to search for the -contract. Once found, you can make write calls to the contract by following the -steps below: +contract. Once found, you can make write calls to the contract in the following +sequence: -1. Click on the "connect wallet" button ++ click on the "connect wallet" button, connect wallet -2. Select Argent X and approve the connection ++ select `Argent X` and approve the connection connect to argentX -3. You can now make read and write calls easily. ++ you can now make read and write calls easily. -# Let's learn Cairo +## Let's learn Cairo -First let's look at a default contract that comes with Protostar +First let's look at a default contract that comes with Protostar which allows +you to set balance on deployment, increase, and get the balance. ```cairo -// Allows you to set balance on deployment, increase, and get the balance. - // Language directive - instructs compiler its a StarkNet contract %lang starknet @@ -155,22 +155,21 @@ from starkware.cairo.common.cairo_builtins import HashBuiltin // @dev Storage variable that stores the balance of a user. // @storage_var is a decorator that instructs the compiler the function -// below it is a storage variable. +// below it is a storage variable. @storage_var -func balance() -> (res: felt) { -} +func balance() -> (res: felt){} // @dev Constructor writes the balance variable to 0 on deployment // Constructors sets storage variables on deployment. Can accept arguments too. @constructor func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}() {balance.write(0); return (); -} + range_check_ptr}() {balance.write(0); return(); + } // @dev increase_balance updates the balance variable // @param amount the amount you want to add to balance // @external is a decorator that specifies the func below it is an external -// function. +// function. @external func increase_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(amount: felt){ @@ -178,10 +177,10 @@ func increase_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, assert_nn(amount); } - let (res) = balance.read(); - balance.write(res + amount); - return (); -} + let (res) = balance.read(); + balance.write(res + amount); + return (); + } // @dev returns the balance variable // @view is a decorator that specifies the func below it is a view function. @@ -190,708 +189,674 @@ func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (res: felt) { let (res) = balance.read(); return (res,); -} - -// before proceeding, try to build, deploy and interact with this contract! -// NB: Should be at main.cairo if you are using Protostar. + } ``` -Now unto the main lessons +Before proceeding to the main lessons, try to build, deploy and interact with +this contract. +NB: You should be at `main.cairo` if you are using Protostar. -### 1. THE FELT DATA TYPE - -```cairo - // Unlike solidity, where you have access to various data types, Cairo - // comes with just a single data type..felts - // Felts stands for Field elements, and are a 252 bit integer in the range - // 0<=x<=P where P is a prime number. - // You can create a Uint256 in Cairo by utlizing a struct of two 128 bits - // felts. - - struct Uint256 { - low: felt, // The low 128 bits of the value. - high: felt, // The high 128 bits of the value. - } - - // To avoid running into issues with divisions, it's safer to work with the - // unsigned_div_rem method from Cairo-lang's library. -``` +### 1. The Felt data type -### 2. LANG DIRECTIVE AND IMPORTS +Unlike solidity, where you have access to various data types, Cairo comes with +just a single data type `..felts`. Felts stands for Field elements, and are a +252 bit integer in the range `0<=x<=P` where `P` is a prime number. You can +create a `Uint256` in Cairo by utlizing a struct of two 128 bits felts. ```cairo - // To get started with writing a StarkNet contract, you must specify the - // directive: - - %lang starknet +struct Uint256{ + low: felt, // The low 128 bits of the value. + high: felt, // The high 128 bits of the value. + } +``` - // This directive informs the compiler you are writing a contract and not a - // program. - // The difference between both is contracts have access to StarkNet's - // storage, programs don't and as such are stateless. +To avoid running into issues with divisions, it's safer to work with the +`unsigned_div_rem` method from Cairo-lang's library. - // There are important functions you might need to import from the official - // Cairo-lang library or Openzeppelin's. e.g. +### 2. Lang Directive and Imports - from starkware.cairo.common.cairo_builtins import HashBuiltin - from cairo_contracts.src.openzeppelin.token.erc20.library import ERC20 - from starkware.cairo.common.uint256 import Uint256 - from starkware.cairo.common.bool import TRUE -``` - -### 3. DATA STRUCTURES +To get started with writing a StarkNet contract, you must specify the directive: ```cairo - // A. STORAGE VARIABLES - // Cairo's storage is a map with 2^251 slots, where each slot is a felt - // which is initialized to 0. - // You create one using the @storage_var decorator - - @storage_var - func names() -> (name: felt){ - } - - // B. STORAGE MAPPINGS - // Unlike soldity where mappings have a separate keyword, in Cairo you - // create mappings using storage variables. - - @storage_var - func names(address: felt) -> (name: felt){ - } - - // C. STRUCTS - // Structs are a means to create custom data types in Cairo. - // A Struct has a size, which is the sum of the sizes of its members. The - // size can be retrieved using MyStruct.SIZE. - // You create a struct in Cairo using the `struct` keyword. - - struct Person { - name: felt, - age: felt, - address: felt, - } - - // D. CONSTANTS - // Constants are fixed and as such can't be altered after being set. - // They evaluate to an integer (field element) at compile time. - // To create a constant in Cairo, you use the `const` keyword. - // Its proper practice to capitalize constant names. - - const USER = -0x01C6cfC1DB2ae90dACEA243F0a8C2F4e32560F7cDD398e4dA2Cc56B733774E9b - - // E. ARRAYS - // Arrays can be defined as a pointer(felt*) to the first element of the - //array. - // As an array is populated, its elements take up contigous memory cells. - // The `alloc` keyword can be used to dynamically allocate a new memory - // segment, which can be used to store an array - - let (myArray: felt*) = alloc (); - assert myArray[0] = 1; - assert myArray[1] = 2; - assert myArray[3] = 3; - - // You can also use the `new` operator to create fixed-size arrays using - //tuples - // The new operator is useful as it enables you allocate memory and - // initialize the object in one instruction - - func foo() { - tempvar arr: felt* = new (1, 1, 2, 3, 5); - assert arr[4] = 5; - return (); - } - - // F. TUPLES - // A tuple is a finite, ordered, unchangeable list of elements - // It is represented as a comma-separated list of elements enclosed by - // parentheses - // Their elements may be of any combination of valid types. - - local tuple0: (felt, felt, felt) = (7, 9, 13); - - // G. EVENTS - // Events allows a contract emit information during the course of its - // execution, that can be used outside of StarkNet. - // To create an event: - - @event - func name_stored(address, name) { - } - - // To emit an event: - - name_stored.emit(address, name); +%lang starknet ``` -### 4. CONSTRUCTORS, EXTERNAL AND VIEW FUNCTIONS +This directive informs the compiler you are writing a contract and not a +program. The difference between both is contracts have access to StarkNet's +storage, programs don't and as such are stateless. + +There are important functions you might need to import from the official +Cairo-lang library or Openzeppelin's, e.g. ```cairo - // A. CONSTRUCTORS - // Constructors are a way to intialize state variables on contract - // deployment - // You create a constructor using the @constructor decorator - - @constructor - func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}(_name: felt) { - let (caller) = get_caller_address(); - names.write(caller, _name); - return (); - } - - // B. EXTERNAL FUNCTIONS - // External functions are functions that modifies the state of the network - // You create an external function using the @external decorator - - @external - func store_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}(_name: felt){ - let (caller) = get_caller_address(); - names.write(caller, _name); - stored_name.emit(caller, _name); - return (); - } - - // C. VIEW FUNCTIONS - // View functions do not modify the state of the blockchain - // You can create a view function using the @view decorator - - @view - func get_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}(_address: felt) -> (name: felt){ - let (name) = names.read(_address); - return (name,); - } - - // NB: Unlike Solidity, Cairo supports just External and View function - // types. - // You can alternatively also create an internal function by not adding any - // decorator to the function. +from starkware.cairo.common.cairo_builtins import HashBuiltin +from cairo_contracts.src.openzeppelin.token.erc20.library import ERC20 +from starkware.cairo.common.uint256 import Uint256 +from starkware.cairo.common.bool import TRUE ``` -### 5. DECORATORS +### 3. Data Structures + ++ Storage variables: Cairo's storage is a map with `2^251` slots, where each + slot is a felt which is initialized to `0`. You create one using the + `@storage_var` decorator + + ```cairo + @storage_var + func names() -> (name: felt){} + ``` + ++ Storage mappings: Unlike soldity where mappings have a separate keyword, in + Cairo you create mappings using storage variables. + + ```cairo + @storage_var + func names(address: felt) -> (name: felt){} + ``` + ++ Structs: are a means to create custom data types in Cairo. A `struct` has a + size, which is the sum of the sizes of its members. The size can be + retrieved using `MyStruct.SIZE`. You create a struct in Cairo using the + `struct` keyword. + + ```cairo + struct Person { + name: felt, + age: felt, + address: felt, + } + ``` + ++ Constants: Constants are fixed and as such can't be altered after being set. + They evaluate to an integer (field element) at compile time. To create a + constant in Cairo, you use the `const` keyword. Its proper practice to + capitalize constant names. + + ```cairo + const USER = 0x01C6cfC1DB2ae90dACEA243F0a8C2F4e32560F7cDD398e4dA2Cc56B733774E9b + ``` + ++ Arrays: Arrays can be defined as a `pointer(felt*)` to the first element of + the array. As an array is populated, its elements take up contigous memory + cells. The `alloc` keyword can be used to dynamically allocate a new memory + segment, which can be used to store an array: + + ```cairo + let (myArray: felt*) = alloc (); + assert myArray[0] = 1; + assert myArray[1] = 2; + assert myArray[3] = 3; + ``` + + You can also use the `new` operator to create fixed-size arrays using + tuples. The new operator is useful as it enables you allocate memory and + initialize the object in one instruction + + ```cairo + func foo() { + tempvar arr: felt* = new (1, 1, 2, 3, 5); + assert arr[4] = 5; + return (); + } + ``` + ++ Tuples: A tuple is a finite, ordered, unchangeable list of elements. It is + represented as a comma-separated list of elements enclosed by parentheses. + Their elements may be of any combination of valid types. + + ```cairo + local tuple0: (felt, felt, felt) = (7, 9, 13); + ``` + ++ Events: Events allows a contract emit information during the course of its + execution, that can be used outside of StarkNet. An event can be created, + subsequently emitted: + + ```cairo + @event + func name_stored(address, name) {} + + name_stored.emit(address, name); + ``` + +### 4. Constructors, External and View functions + ++ Constructors: Constructors are a way to intialize state variables on + contract deployment. You create a constructor using the `@constructor` + decorator. + + ```cairo + @constructor + func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}(_name: felt) { + let (caller) = get_caller_address(); + names.write(caller, _name); + return (); + } + ``` + ++ External functions: External functions are functions that modifies the state + of the network. You create an external function using the `@external` + decorator: + + ```cairo + @external + func store_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}(_name: felt){ + let (caller) = get_caller_address(); + names.write(caller, _name); + stored_name.emit(caller, _name); + return (); + } + ``` + ++ View functions: View functions do not modify the state of the blockchain. + You can create a view function using the `@view` decorator. + + ```cairo + @view + func get_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}(_address: felt) -> (name: felt){ + let (name) = names.read(_address); + return (name,); + } + ``` + + NB: Unlike Solidity, Cairo supports just External and View function types. + You can alternatively also create an internal function by not adding any + decorator to the function. + +### 5. Decorators + +All functions in Cairo are specified by the `func` keyword, which can be +confusing. Decorators are used by the compiler to distinguish between these +functions. + +Here are the most common decorators you'll encounter in Cairo: + ++ `@storage_var` — used for specifying state variables. ++ `@constructor` — used for specifying constructors. ++ `@external` — used for specifying functions that write to a state variable. ++ `@event` — used for specifying events ++ `@view` — used to specify functions reading from a state variable ++ `@contract_interface` — used for specifying function interfaces. ++ `@l1_handler` — used for specifying functions that processes message sent from + an L1 contract in a messaging bridge. + +### 6. BUILTINS, HINTS & IMPLICIT Arguments + ++ `BUILTINS` are predefined optimized low-level execution units, which are + added to Cairo’s CPU board. They help perform predefined computations like + pedersen hashing, bitwise operations etc, which are expensive to perform in + Vanilla Cairo. Each builtin in Cairo is assigned a separate memory location, + accessible through regular Cairo memory calls using implicit parameters. You + specify them using the `%builtins` directive + + Here is a list of available builtins in Cairo: + + + `output` — the output builtin is used for writing program outputs + + `pedersen` — the pedersen builtin is used for pedersen hashing + computations + + `range_check` — This builtin is mostly used for integer comparisons, + and facilitates check to confirm that a field element is within a range + `[0, 2^128)` + + `ecdsa` — the ecdsa builtin is used for verifying ECDSA signatures + + `bitwise` — the bitwise builtin is used for carrying out bitwise + operations on felts + ++ `HINTS` are pieces of Python codes, which contains instructions that only + the prover sees and executes. From the point of view of the verifier these + hints do not exist. To specify a hint in Cairo, you need to encapsulate it + within `%{` and `%}`. It is good practice to avoid using hints as much as + you can in your contracts, as hints are not added to the bytecode, and thus + do not count in the total number of execution steps. + + ```cairo + %{ + # Python hint goes here + %} + ``` + ++ `IMPLICIT ARGUMENTS` are not restricted to the function body, but can be + inherited by other functions calls that require them. Implicit arguments are + passed in between curly bracelets, like you can see below: + + ```cairo + func store_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}(_name: felt){ + let (caller) = get_caller_address(); + names.write(caller, _name); + stored_name.emit(caller, _name); + return (); + } + ``` + +### 7. Error Messages and Access Controls + +You can create custom errors in Cairo which is outputted to the user upon failed +execution. This can be very useful for implementing checks and proper access +control mechanisms. An example is preventing a user to call a function except +user is `admin`. ```cairo - // All functions in Cairo are specified by the `func` keyword, which can be - // confusing. - // Decorators are used by the compiler to distinguish between these - // functions. - - // Here are the most common decorators you'll encounter in Cairo: - - // 1. @storage_var — used for specifying state variables. - // 2. @constructor — used for specifying constructors. - // 3. @external — used for specifying functions that write to a state - // variable. - // 4. @event — used for specifying events - // 5. @view — used for specifying functions that reads from a state - // variable. - // 6. @contract_interface - used for specifying function interfaces. - // 7. @l1_handler — used for specifying functions that processes message - // sent from an L1 contract in a messaging bridge. -``` +// imports +from starkware.starknet.common.syscalls import get_caller_address -### 6. BUILTINS, HINTS & IMPLICIT ARGUMENTS +// create an admin constant +const ADMIN = 0x01C6cfC1DB2ae90dACEA243F0a8C2F4e32560F7cDD398e4dA2Cc56B733774E9b -```cairo - // A. BUILTINS - // Builtins are predefined optimized low-level execution units, which are - // added to Cairo’s CPU board. - // They help perform predefined computations like pedersen hashing, bitwise - // operations etc, which are expensive to perform in Vanilla Cairo. - // Each builtin in Cairo, is assigned a separate memory location, - // accessible through regular Cairo memory calls using implicit parameters. - // You specify them using the %builtins directive - - // Here is a list of available builtins in Cairo: - // 1. output — the output builtin is used for writing program outputs - // 2. pedersen — the pedersen builtin is used for pedersen hashing - // computations - // 3. range_check — This builtin is mostly used for integer comparisons, - // and facilitates check to confirm that a field element is within a range [0, - // 2^128) - // 4. ecdsa — the ecdsa builtin is used for verifying ECDSA signatures - // 5. bitwise — the bitwise builtin is used for carrying out bitwise - // operations on felts - - // B. HINTS - // Hints are pieces of Python codes, which contains instructions that only - // the prover sees and executes - // From the point of view of the verifier these hints do not exist - // To specify a hint in Cairo, you need to encapsulate it within %{ and%} - // Its good practice to avoid using hints as much as you can in your - // contracts, as hints are not added to the bytecode, and thus do not count in the - // total number of execution steps. - - %{ - # Python hint goes here - %} - - // C. IMPLICIT ARGUMENTS - // Implicit arguments are not restricted to the function body, but can be - // inherited by other functions calls that require them. - // Implicit arguments are passed in between curly bracelets, like you can - // see below: - - func store_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}(_name: felt){ - let (caller) = get_caller_address(); - names.write(caller, _name); - stored_name.emit(caller, _name); - return (); - } +// implement access control +with_attr error_message("You do not have access to make this action!"){ + let (caller) = get_caller_address(); + assert ADMIN = caller; + } + +// using an assert statement throws if condition is not true, thus +// returning the specified error. ``` -### 7. ERROR MESSAGES & ACCESS CONTROLS +### 8. Contract Interfaces + +Contract interfaces provide a means for one contract to invoke or call the +external function of another contract. To create a contract interface, you use +the `@contract_interface` keyword: ```cairo - // You can create custom errors in Cairo which is outputted to the user - // upon failed execution. - // This can be very useful for implementing checks and proper access - // control mechanisms. - // An example is preventing a user to call a function except user is admin. - - // imports - from starkware.starknet.common.syscalls import get_caller_address - - // create an admin constant - const ADMIN = -0x01C6cfC1DB2ae90dACEA243F0a8C2F4e32560F7cDD398e4dA2Cc56B733774E9b - - // implement access control - with_attr error_message("You do not have access to make this action!"){ - let (caller) = get_caller_address(); - assert ADMIN = caller; +@contract_interface + namespace IENS { + func store_name(_name: felt) { } - // using an assert statement throws if condition is not true, thus - // returning the specified error. + func get_name(_address: felt) -> (name: felt) { + } + } ``` -### 8. CONTRACT INTERFACES +Once a contract interface is specified, any contract can make calls to that +contract passing in the contract address as the first parameter like this: ```cairo - // Contract interfaces provide a means for one contract to invoke or call - // the external function of another contract. - // To create a contract interface, you use the @contract_interface keyword - - @contract_interface - namespace IENS { - func store_name(_name: felt) { - } - - func get_name(_address: felt) -> (name: felt) { - } - } - - // Once a contract interface is specified, any contract can make calls to - // that contract passing in the contract address as the first parameter like this: - - IENS.store_name(contract_address, _name); - - // Note that Interfaces excludes the function body/logic and the implicit - // arguments. +IENS.store_name(contract_address, _name); ``` -### 9. RECURSIONS +Note that Interfaces excludes the function body/logic and the implicit +arguments. -```cairo - // Due to the unavailability of loops, Recursions are the go-to for similar - // operations. - // In simple terms, a recursive function is one which calls itself - // repeatedly. - - // A good example to demonstrate this is writing a function for getting the - // nth fibonacci number: - - @external - func fibonacci{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}(n : felt) -> (result : felt){ - alloc_locals; - if (n == 0){ - return (0); - } - if (n == 1){ - return (1); - } - let (local x) = fibonacci(n - 1); - let (local y) = fibonacci(n - 2); - return (result=(x + y)); - } - - // The nth fibonacci term is the sum of the nth - 1 and the nth - 2 - // numbers, that's why we get these two as (x, y) using recursion. - // NB: when implementing recursive functions, always remember to implement - // a base case (n==0, n==1 in our case), to prevent stack overflow. -``` +### 9. Recursions -Some low-level stuffs +Due to the unavailability of loops, Recursions are the go-to for similar +operations. In simple terms, a recursive function is one which calls itself +repeatedly. -### 10. REGISTERS +A good example to demonstrate this is writing a function for getting the nth +fibonacci number: ```cairo - // Registers holds values that may change over time. - - // There are 3 major types of Registers: - // 1. ap (allocation pointer) points to a yet unused memory. Temporary - // variables created using `let`, `tempvar` are held here, and thus susceptible to - // being revoked - // 2. fp (frame pointer) points to the frame of the current function. The - // address of all the function arguments and local variables are relative to this - // register and as such can never be revoked - // 3. pc (program counter) points to the current instruction +@external +func fibonacci{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}(n : felt) -> (result : felt){ + alloc_locals; + if (n == 0){ + return (0); + } + if (n == 1){ + return (1); + } + let (local x) = fibonacci(n - 1); + let (local y) = fibonacci(n - 2); + return (result=(x + y)); + } ``` -### 11. REVOKED REFERENCES +The nth fibonacci term is the sum of the `nth - 1` and the `nth - 2` numbers, +that's why we get these two as `(x,y)` using recursion. -```cairo - // Revoked references occurs when there is a call instruction to another - // function, between the definition of a reference variable that depends on - // `ap`(temp variables) and its usage. This occurs as the compiler may not be able - // to compute the change of `ap` (as one may jump to the label from another place - // in the program, or call a function that might change ap in an unknown way). - - // Here is an example to demonstrate what I mean: - - @external - func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}() -> (res: felt) { - return (res=100); - } - - @external - func double_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}() -> (res: felt) { - let multiplier = 2; - let (balance) = get_balance(); - let new_balance = balance * multiplier; - return (res=new_balance); - } - - // If you run that code, you'll run into the revoked reference error as we - // are trying to access the `multiplier` variable after calling the get_balance - // function; - - // To solve revoked references, In simple cases you can resolve this issue, - // by adding the keyword, `alloc_locals` within function scopes, but in most - // complex cases you might need to create a local variable to resolve it. - - // resolving the `double_balance` function: - @external - func double_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}() -> (res: felt) { - alloc_locals; - let multiplier = 2; - let (balance) = get_balance(); - let new_balance = balance * multiplier; - return (res=new_balance); - } -``` +NB: when implementing recursive functions, always remember to implement a base +case (`n==0`, `n==1` in our case), to prevent stack overflow. -Miscellaneous +### 10. Registers -### 12. Understanding Cairo's punctuations +Registers holds values that may change over time. There are 3 major types of +registers: -```cairo - // ; (semicolon). Used at the end of each instruction ++ `ap` (allocation pointer) points to a yet unused memory. Temporary variables + created using `let`, `tempvar` are held here, and thus susceptible to being + revoked. ++ `fp` (frame pointer) points to the frame of the current function. The address + of all the function arguments and local variables are relative to this + register and as such can never be revoked. ++ `pc` (program counter) points to the current instruction. - // ( ) (parentheses). Used in a function declaration, if statements, and in - // a tuple declaration +### 11. Revoked References - // { } (curly brackets). Used in a declaration of implicit arguments and to - // define code blocks. +Revoked references occurs when there is a call instruction to another function, +between the definition of a reference variable that depends on `ap`(temp +variables) and its usage. This occurs as the compiler may not be able to compute +the change of `ap` (as one may jump to the label from another place in the +program, or call a function that might change ap in an unknown way). - // [ ] (square brackets). Standalone brackets represent the value at a - // particular address location (such as the allocation pointer, [ap]). Brackets - // following a pointer or a tuple act as a subscript operator, where x[2] - // represents the element with index 2 in x. +Here is an example to demonstrate what I mean: - // * Single asterisk. Refers to the pointer of an expression. +```cairo +@external +func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}() -> (res: felt) { + return (res=100); + } - // % Percent sign. Appears at the start of a directive, such as %builtins - // or %lang. +@external +func double_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}() -> (res: felt) { + let multiplier = 2; + let (balance) = get_balance(); + let new_balance = balance * multiplier; + return (res=new_balance); + } +``` - // %{ %} Represents Python hints. +If you run that code, you'll run into the revoked reference error as we are +trying to access the `multiplier` variable after calling the `get_balance` +function. - // _ (underscore). A placeholder to handle values that are not used, such - // as an unused function return value. +In simple cases you can resolve revoked references by adding the keyword +`alloc_locals` within function scopes. In most complex cases you might need to +create a local variable to resolve it. + +```cairo +// resolving the `double_balance` function: +@external +func double_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}() -> (res: felt) { + alloc_locals; + let multiplier = 2; + let (balance) = get_balance(); + let new_balance = balance * multiplier; + return (res=new_balance); + } ``` -# FULL CONTRACT EXAMPLE +### 12. Understanding Cairo's Punctuations + ++ `;` (semicolon). Used at the end of each instruction ++ `()` (parentheses). Used in a function declaration, if statements, and in a + tuple declaration ++ `{}` (curly braces). Used in a declaration of implicit arguments and to define + code blocks. ++ `[]` (square brackets). Standalone brackets represent the value at a + particular address location (such as the allocation pointer, `[ap]`). Brackets + following a pointer or a tuple act as a subscript operator, where `x[2]` + represents the element with index `2` in `x`. ++ `*` (single asterisk). Refers to the pointer of an expression. ++ `%` (percent sign). Appears at the start of a directive, such as `%builtins` + or `%lang`. ++ `%{` and `%}` represent Python hints. ++ `_` (underscore). A placeholder to handle values that are not used, such as an + unused function return value. + +## Full Contract Example Below is a simple automated market maker contract example that implements most of what we just learnt! Re-write, deploy, have fun! ```cairo - %lang starknet +%lang starknet - from starkware.cairo.common.cairo_builtins import HashBuiltin - from starkware.cairo.common.hash import hash2 - from starkware.cairo.common.alloc import alloc - from starkware.cairo.common.math import (assert_le, assert_nn_le, - unsigned_div_rem) - from starkware.starknet.common.syscalls import (get_caller_address, - storage_read, storage_write) +from starkware.cairo.common.cairo_builtins import HashBuiltin +from starkware.cairo.common.hash import hash2 +from starkware.cairo.common.alloc import alloc +from starkware.cairo.common.math import (assert_le, assert_nn_le, + unsigned_div_rem) +from starkware.starknet.common.syscalls import (get_caller_address, + storage_read, storage_write) - // - // CONSTANTS - // +// CONSTANTS +// +// @dev the maximum amount of each token that belongs to the AMM +const BALANCE_UPPER_BOUND = 2 ** 64; - // @dev the maximum amount of each token that belongs to the AMM - const BALANCE_UPPER_BOUND = 2 ** 64; +const TOKEN_TYPE_A = 1; +const TOKEN_TYPE_B = 2; - const TOKEN_TYPE_A = 1; - const TOKEN_TYPE_B = 2; +// @dev Ensure the user's balances are much smaller than the pool's balance +const POOL_UPPER_BOUND = 2 ** 30; +const ACCOUNT_BALANCE_BOUND = 1073741; // (2 ** 30 / 1000) - // @dev Ensure the user's balances are much smaller than the pool's balance - const POOL_UPPER_BOUND = 2 ** 30; - const ACCOUNT_BALANCE_BOUND = 1073741; // (2 ** 30 / 1000) - // - // STORAGE VARIABLES - // +// STORAGE VARIABLES +// +// @dev A map from account and token type to corresponding balance +@storage_var +func account_balance(account_id: felt, token_type: felt) -> (balance: felt){} - // @dev A map from account and token type to corresponding balance - @storage_var - func account_balance(account_id: felt, token_type: felt) -> (balance: felt){ - } +// @dev a map from token type to corresponding pool balance +@storage_var +func pool_balance(token_type: felt) -> (balance: felt) {} - // @dev a map from token type to corresponding pool balance - @storage_var - func pool_balance(token_type: felt) -> (balance: felt) { - } - // - // GETTERS - // - - // @dev returns account balance for a given token - // @param account_id Account to be queried - // @param token_type Token to be queried - @view - func get_account_token_balance{syscall_ptr: felt*, pedersen_ptr: - HashBuiltin*, range_check_ptr}( - account_id: felt, token_type: felt +// GETTERS +// +// @dev returns account balance for a given token +// @param account_id Account to be queried +// @param token_type Token to be queried +@view +func get_account_token_balance{syscall_ptr: felt*, pedersen_ptr: + HashBuiltin*, range_check_ptr}( + account_id: felt, token_type: felt ) -> (balance: felt) { - return account_balance.read(account_id, token_type); - } + return account_balance.read(account_id, token_type); + } - // @dev return the pool's balance - // @param token_type Token type to get pool balance - @view - func get_pool_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}( - token_type: felt +// @dev return the pool's balance +// @param token_type Token type to get pool balance +@view +func get_pool_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}( + token_type: felt ) -> (balance: felt) { - return pool_balance.read(token_type); - } - - // - // EXTERNALS - // - - // @dev set pool balance for a given token - // @param token_type Token whose balance is to be set - // @param balance Amount to be set as balance - @external - func set_pool_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}( - token_type: felt, balance: felt - ) { - with_attr error_message("exceeds maximum allowed tokens!"){ - assert_nn_le(balance, BALANCE_UPPER_BOUND - 1); - } + return pool_balance.read(token_type); + } - pool_balance.write(token_type, balance); - return (); - } - - // @dev add demo token to the given account - // @param token_a_amount amount of token a to be added - // @param token_b_amount amount of token b to be added - @external - func add_demo_token{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}( - token_a_amount: felt, token_b_amount: felt - ) { - alloc_locals; - let (account_id) = get_caller_address(); - - modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_A, - amount=token_a_amount); - modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_B, - amount=token_b_amount); - - return (); - } - // @dev intialize AMM - // @param token_a amount of token a to be set in pool - // @param token_b amount of token b to be set in pool - @external - func init_pool{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}( - token_a: felt, token_b: felt +// EXTERNALS +// +// @dev set pool balance for a given token +// @param token_type Token whose balance is to be set +// @param balance Amount to be set as balance +@external +func set_pool_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}( + token_type: felt, balance: felt ) { - with_attr error_message("exceeds maximum allowed tokens!"){ - assert_nn_le(token_a, POOL_UPPER_BOUND - 1); - assert_nn_le(token_b, POOL_UPPER_BOUND - 1); - } - - set_pool_token_balance(token_type=TOKEN_TYPE_A, balance=token_a); - set_pool_token_balance(token_type=TOKEN_TYPE_B, balance=token_b); - - return (); + with_attr error_message("exceeds maximum allowed tokens!"){ + assert_nn_le(balance, BALANCE_UPPER_BOUND - 1); } + pool_balance.write(token_type, balance); + return (); + } - // @dev swaps token between the given account and the pool - // @param token_from token to be swapped - // @param amount_from amount of token to be swapped - // @return amount_to the token swapped to - @external - func swap{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - token_from: felt, amount_from: felt - ) -> (amount_to: felt) { - alloc_locals; - let (account_id) = get_caller_address(); - - // verify token_from is TOKEN_TYPE_A or TOKEN_TYPE_B - with_attr error_message("token not allowed in pool!"){ - assert (token_from - TOKEN_TYPE_A) * (token_from - TOKEN_TYPE_B) = 0; - } - - // check requested amount_from is valid - with_attr error_message("exceeds maximum allowed tokens!"){ - assert_nn_le(amount_from, BALANCE_UPPER_BOUND - 1); - } - - // check user has enough funds - let (account_from_balance) = - get_account_token_balance(account_id=account_id, token_type=token_from); - with_attr error_message("insufficient balance!"){ - assert_le(amount_from, account_from_balance); - } - - let (token_to) = get_opposite_token(token_type=token_from); - let (amount_to) = do_swap(account_id=account_id, token_from=token_from, - token_to=token_to, amount_from=amount_from); - - return (amount_to=amount_to); - } - - - // - // INTERNALS - // - - // @dev internal function that updates account balance for a given token - // @param account_id Account whose balance is to be modified - // @param token_type Token type to be modified - // @param amount Amount Amount to be added - func modify_account_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}( - account_id: felt, token_type: felt, amount: felt +// @dev add demo token to the given account +// @param token_a_amount amount of token a to be added +// @param token_b_amount amount of token b to be added +@external +func add_demo_token{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}( + token_a_amount: felt, token_b_amount: felt + ) { + alloc_locals; + let (account_id) = get_caller_address(); + + modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_A, + amount=token_a_amount); + modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_B, + amount=token_b_amount); + + return (); + } + +// @dev intialize AMM +// @param token_a amount of token a to be set in pool +// @param token_b amount of token b to be set in pool +@external +func init_pool{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, + range_check_ptr}( + token_a: felt, token_b: felt ) { - let (current_balance) = account_balance.read(account_id, token_type); - tempvar new_balance = current_balance + amount; + with_attr error_message("exceeds maximum allowed tokens!"){ + assert_nn_le(token_a, POOL_UPPER_BOUND - 1); + assert_nn_le(token_b, POOL_UPPER_BOUND - 1); + } - with_attr error_message("exceeds maximum allowed tokens!"){ - assert_nn_le(new_balance, BALANCE_UPPER_BOUND - 1); - } + set_pool_token_balance(token_type=TOKEN_TYPE_A, balance=token_a); + set_pool_token_balance(token_type=TOKEN_TYPE_B, balance=token_b); - account_balance.write(account_id=account_id, token_type=token_type, - value=new_balance); - return (); - } + return (); + } - // @dev internal function that swaps tokens between the given account and - // the pool - // @param account_id Account whose tokens are to be swapped - // @param token_from Token type to be swapped from - // @param token_to Token type to be swapped to - // @param amount_from Amount to be swapped - func do_swap{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}( - account_id: felt, token_from: felt, token_to: felt, amount_from: felt - ) -> (amount_to: felt) { - alloc_locals; - - // get pool balance - let (local amm_from_balance) = get_pool_token_balance(token_type = - token_from); - let (local amm_to_balance) = - get_pool_token_balance(token_type=token_to); - - // calculate swap amount - let (local amount_to, _) = unsigned_div_rem((amm_to_balance * - amount_from), (amm_from_balance + amount_from)); - - // update token_from balances - modify_account_balance(account_id=account_id, token_type=token_from, - amount=-amount_from); - set_pool_token_balance(token_type=token_from, balance=(amm_from_balance - + amount_from)); - - // update token_to balances - modify_account_balance(account_id=account_id, token_type=token_to, - amount=amount_to); - set_pool_token_balance(token_type=token_to, balance=(amm_to_balance - - amount_to)); - - return (amount_to=amount_to); - } - // @dev internal function to get the opposite token type - // @param token_type Token whose opposite pair needs to be gotten - func get_opposite_token(token_type: felt) -> (t: felt) { - if(token_type == TOKEN_TYPE_A) { - return (t=TOKEN_TYPE_B); - } else { - return (t=TOKEN_TYPE_A); - } +// @dev swaps token between the given account and the pool +// @param token_from token to be swapped +// @param amount_from amount of token to be swapped +// @return amount_to the token swapped to +@external +func swap{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + token_from: felt, amount_from: felt + ) -> (amount_to: felt) { + alloc_locals; + let (account_id) = get_caller_address(); + + // verify token_from is TOKEN_TYPE_A or TOKEN_TYPE_B + with_attr error_message("token not allowed in pool!"){ + assert (token_from - TOKEN_TYPE_A) * (token_from - TOKEN_TYPE_B) = 0; + } + + // check requested amount_from is valid + with_attr error_message("exceeds maximum allowed tokens!"){ + assert_nn_le(amount_from, BALANCE_UPPER_BOUND - 1); + } + + // check user has enough funds + let (account_from_balance) = + get_account_token_balance(account_id=account_id, token_type=token_from); + with_attr error_message("insufficient balance!"){ + assert_le(amount_from, account_from_balance); + } + + let (token_to) = get_opposite_token(token_type=token_from); + let (amount_to) = do_swap(account_id=account_id, token_from=token_from, + token_to=token_to, amount_from=amount_from); + + return (amount_to=amount_to); + } + + +// INTERNALS +// +// @dev internal function that updates account balance for a given token +// @param account_id Account whose balance is to be modified +// @param token_type Token type to be modified +// @param amount Amount Amount to be added +func modify_account_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, +range_check_ptr}( + account_id: felt, token_type: felt, amount: felt + ) { + let (current_balance) = account_balance.read(account_id, token_type); + tempvar new_balance = current_balance + amount; + + with_attr error_message("exceeds maximum allowed tokens!"){ + assert_nn_le(new_balance, BALANCE_UPPER_BOUND - 1); + } + + account_balance.write(account_id=account_id, token_type=token_type, + value=new_balance); + return (); + } + +// @dev internal function that swaps tokens between the given account and +// the pool +// @param account_id Account whose tokens are to be swapped +// @param token_from Token type to be swapped from +// @param token_to Token type to be swapped to +// @param amount_from Amount to be swapped +func do_swap{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, +range_check_ptr}( + account_id: felt, token_from: felt, token_to: felt, amount_from: felt + ) -> (amount_to: felt) { + alloc_locals; + + // get pool balance + let (local amm_from_balance) = get_pool_token_balance(token_type = + token_from); + let (local amm_to_balance) = get_pool_token_balance(token_type=token_to); + + // calculate swap amount + let (local amount_to, _) = unsigned_div_rem((amm_to_balance * + amount_from), (amm_from_balance + amount_from)); + + // update token_from balances + modify_account_balance(account_id=account_id, token_type=token_from, + amount=-amount_from); + set_pool_token_balance(token_type=token_from, balance=(amm_from_balance + + amount_from)); + + // update token_to balances + modify_account_balance(account_id=account_id, token_type=token_to, + amount=amount_to); + set_pool_token_balance(token_type=token_to, balance=(amm_to_balance - + amount_to)); + + return (amount_to=amount_to); + } + + + // @dev internal function to get the opposite token type + // @param token_type Token whose opposite pair needs to be gotten + func get_opposite_token(token_type: felt) -> (t: felt) { + if(token_type == TOKEN_TYPE_A) { + return (t=TOKEN_TYPE_B); + } else { + return (t=TOKEN_TYPE_A); } + } ``` -# Additional Resources +## Additional Resources -1. [Official documentation](https://www.cairo-lang.org/docs/) -2. [Starknet EDU](https://medium.com/starknet-edu) -3. [Journey through Cairo](https://medium.com/@darlingtonnnam/journey-through-cairo-i-setting-up-protostar-and-argentx-for-local-development-ba40ae6c5524) -4. [Demystifying Cairo whitepaper](https://medium.com/@pban/demystifying-cairo-white-paper-part-i-b71976ad0108) -5. [Learn about StarkNet with Argent](https://www.argent.xyz/learn/tag/starknet/) ++ [Official documentation](https://www.cairo-lang.org/docs/) ++ [Starknet EDU](https://medium.com/starknet-edu) ++ [Journey through Cairo](https://medium.com/@darlingtonnnam/journey-through-cairo-i-setting-up-protostar-and-argentx-for-local-development-ba40ae6c5524) ++ [Demystifying Cairo whitepaper](https://medium.com/@pban/demystifying-cairo-white-paper-part-i-b71976ad0108) ++ [Learn about StarkNet with Argent](https://www.argent.xyz/learn/tag/starknet/) -# Development Frameworks +## Development Frameworks -1. [Protostar](https://docs.swmansion.com/protostar/docs/tutorials/installation) -2. [Nile](https://github.com/OpenZeppelin/nile) -3. [StarkNet CLI](https://www.cairo-lang.org/docs/quickstart.html) ++ [Protostar](https://docs.swmansion.com/protostar/docs/tutorials/installation) ++ [Nile](https://github.com/OpenZeppelin/nile) ++ [StarkNet CLI](https://www.cairo-lang.org/docs/quickstart.html) -# Helpful Libraries +## Helpful Libraries -1. [Cairo-lang](https://github.com/starkware-libs/cairo-lang) -2. [Openzeppelin](https://github.com/OpenZeppelin/cairo-contracts) ++ [Cairo-lang](https://github.com/starkware-libs/cairo-lang) ++ [Openzeppelin](https://github.com/OpenZeppelin/cairo-contracts) -# Educational Repos +## Educational Repos -1. [StarkNet Cairo 101](https://github.com/starknet-edu/starknet-cairo-101) -2. [StarkNet ERC721](https://github.com/starknet-edu/starknet-erc721) -3. [StarkNet ERC20](https://github.com/starknet-edu/starknet-erc20) -4. [L1 -> L2 Messaging](https://github.com/starknet-edu/starknet-messaging-bridge) -5. [StarkNet Debug](https://github.com/starknet-edu/starknet-debug) -6. [StarkNet Accounts](https://github.com/starknet-edu/starknet-accounts) -7. [Min-Starknet](https://github.com/Darlington02/min-starknet) ++ [StarkNet Cairo 101](https://github.com/starknet-edu/starknet-cairo-101) ++ [StarkNet ERC721](https://github.com/starknet-edu/starknet-erc721) ++ [StarkNet ERC20](https://github.com/starknet-edu/starknet-erc20) ++ [L1 -> L2 Messaging](https://github.com/starknet-edu/starknet-messaging-bridge) ++ [StarkNet Debug](https://github.com/starknet-edu/starknet-debug) ++ [StarkNet Accounts](https://github.com/starknet-edu/starknet-accounts) ++ [Min-Starknet](https://github.com/Darlington02/min-starknet) -# Security +## Security -1. [Amarna static analysis for Cairo programs](https://blog.trailofbits.com/2022/04/20/amarna-static-analysis-for-cairo-programs/) -2. [Cairo and StarkNet security by Ctrl03](https://ctrlc03.github.io/) -3. [How to hack almost any Cairo smart contract](https://medium.com/ginger-security/how-to-hack-almost-any-starknet-cairo-smart-contract-67b4681ac0f6) -4. [Analyzing Cairo code using Armana](https://dic0de.substack.com/p/analyzing-cairo-code-using-amarna?sd=pf) ++ [Amarna static analysis for Cairo programs](https://blog.trailofbits.com/2022/04/20/amarna-static-analysis-for-cairo-programs/) ++ [Cairo and StarkNet security by Ctrl03](https://ctrlc03.github.io/) ++ [How to hack almost any Cairo smart contract](https://medium.com/ginger-security/how-to-hack-almost-any-starknet-cairo-smart-contract-67b4681ac0f6) ++ [Analyzing Cairo code using Armana](https://dic0de.substack.com/p/analyzing-cairo-code-using-amarna?sd=pf) -# Future TO-DOs +## Future TO-DOs Update tutorial to fit Cairo 1.0 -- cgit v1.2.3 From 1c3006859294327a52c8cb1681ffadc3cb7bd3db Mon Sep 17 00:00:00 2001 From: Darlington02 Date: Tue, 31 Jan 2023 22:16:37 +0100 Subject: added images --- cairo.html.markdown | 10 +++++----- images/cairo/build.png | Bin 0 -> 292865 bytes images/cairo/connect.png | Bin 0 -> 62073 bytes images/cairo/connect2.png | Bin 0 -> 66962 bytes images/cairo/declare.png | Bin 0 -> 768881 bytes images/cairo/deploy.png | Bin 0 -> 812958 bytes 6 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 images/cairo/build.png create mode 100644 images/cairo/connect.png create mode 100644 images/cairo/connect2.png create mode 100644 images/cairo/declare.png create mode 100644 images/cairo/deploy.png diff --git a/cairo.html.markdown b/cairo.html.markdown index 18ac81af..95008a78 100644 --- a/cairo.html.markdown +++ b/cairo.html.markdown @@ -72,7 +72,7 @@ protostar build And you should get an output similar to what you see below, with a `main.json` and `main_abi.json` files created in the `build` folder. -building your contract +building your contract ### Declaring Contracts @@ -103,7 +103,7 @@ where `network` specifies the network we are deploying to, `account` specifies account whose private key we are using, `max-fee` specifies the maximum fee to be paid for the transaction. You should get the class hash outputted as seen below: -declaring your contract +declaring your contract ### Deploying Contracts @@ -120,7 +120,7 @@ protostar \ where `0x02a5de1b145e18dfeb31c7cd7ff403714ededf5f3fdf75f8b0ac96f2017541bc` is the class hash of our contract. -deploying your contract +deploying your contract ### Interacting with Contracts @@ -135,9 +135,9 @@ contract. Once found, you can make write calls to the contract in the following sequence: + click on the "connect wallet" button, - connect wallet + connect wallet + select `Argent X` and approve the connection - connect to argentX + connect to argentX + you can now make read and write calls easily. ## Let's learn Cairo diff --git a/images/cairo/build.png b/images/cairo/build.png new file mode 100644 index 00000000..ebb7d8dc Binary files /dev/null and b/images/cairo/build.png differ diff --git a/images/cairo/connect.png b/images/cairo/connect.png new file mode 100644 index 00000000..86146353 Binary files /dev/null and b/images/cairo/connect.png differ diff --git a/images/cairo/connect2.png b/images/cairo/connect2.png new file mode 100644 index 00000000..08b00a81 Binary files /dev/null and b/images/cairo/connect2.png differ diff --git a/images/cairo/declare.png b/images/cairo/declare.png new file mode 100644 index 00000000..174aea34 Binary files /dev/null and b/images/cairo/declare.png differ diff --git a/images/cairo/deploy.png b/images/cairo/deploy.png new file mode 100644 index 00000000..f637b706 Binary files /dev/null and b/images/cairo/deploy.png differ -- cgit v1.2.3 From aced78c444899427f2f5180847ebe11e3b4dd5a3 Mon Sep 17 00:00:00 2001 From: Darlington02 Date: Wed, 1 Feb 2023 15:41:33 +0100 Subject: optimized images --- images/cairo/build.png | Bin 292865 -> 20768 bytes images/cairo/declare.png | Bin 768881 -> 74011 bytes images/cairo/deploy.png | Bin 812958 -> 99481 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/images/cairo/build.png b/images/cairo/build.png index ebb7d8dc..7cadb9ad 100644 Binary files a/images/cairo/build.png and b/images/cairo/build.png differ diff --git a/images/cairo/declare.png b/images/cairo/declare.png index 174aea34..5b5196ce 100644 Binary files a/images/cairo/declare.png and b/images/cairo/declare.png differ diff --git a/images/cairo/deploy.png b/images/cairo/deploy.png index f637b706..bdb7e53c 100644 Binary files a/images/cairo/deploy.png and b/images/cairo/deploy.png differ -- cgit v1.2.3 From 741e0f4a7f4078f1a8a5ae5c7af641477ec53fbd Mon Sep 17 00:00:00 2001 From: Darlington02 Date: Mon, 6 Feb 2023 15:04:37 +0100 Subject: updated cairo.html.markdown --- cairo.html.markdown | 292 ++++++++++++++++++++++++++-------------------------- 1 file changed, 146 insertions(+), 146 deletions(-) diff --git a/cairo.html.markdown b/cairo.html.markdown index 95008a78..e6a04b67 100644 --- a/cairo.html.markdown +++ b/cairo.html.markdown @@ -180,7 +180,7 @@ func increase_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, let (res) = balance.read(); balance.write(res + amount); return (); - } +} // @dev returns the balance variable // @view is a decorator that specifies the func below it is a view function. @@ -189,7 +189,7 @@ func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (res: felt) { let (res) = balance.read(); return (res,); - } +} ``` Before proceeding to the main lessons, try to build, deploy and interact with @@ -204,10 +204,10 @@ just a single data type `..felts`. Felts stands for Field elements, and are a create a `Uint256` in Cairo by utlizing a struct of two 128 bits felts. ```cairo -struct Uint256{ +struct Uint256 { low: felt, // The low 128 bits of the value. high: felt, // The high 128 bits of the value. - } +} ``` To avoid running into issues with divisions, it's safer to work with the @@ -239,19 +239,19 @@ from starkware.cairo.common.bool import TRUE + Storage variables: Cairo's storage is a map with `2^251` slots, where each slot is a felt which is initialized to `0`. You create one using the - `@storage_var` decorator + `@storage_var` decorator. ```cairo @storage_var - func names() -> (name: felt){} + func names() -> (name: felt) {} ``` -+ Storage mappings: Unlike soldity where mappings have a separate keyword, in ++ Storage mappings: Unlike Solidity where mappings have a separate keyword, in Cairo you create mappings using storage variables. ```cairo @storage_var - func names(address: felt) -> (name: felt){} + func names(address: felt) -> (name: felt) {} ``` + Structs: are a means to create custom data types in Cairo. A `struct` has a @@ -269,7 +269,7 @@ from starkware.cairo.common.bool import TRUE + Constants: Constants are fixed and as such can't be altered after being set. They evaluate to an integer (field element) at compile time. To create a - constant in Cairo, you use the `const` keyword. Its proper practice to + constant in Cairo, you use the `const` keyword. It's proper practice to capitalize constant names. ```cairo @@ -423,11 +423,11 @@ Here are the most common decorators you'll encounter in Cairo: ```cairo func store_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}(_name: felt){ - let (caller) = get_caller_address(); - names.write(caller, _name); - stored_name.emit(caller, _name); - return (); + range_check_ptr}(_name: felt){ + let (caller) = get_caller_address(); + names.write(caller, _name); + stored_name.emit(caller, _name); + return (); } ``` @@ -479,12 +479,12 @@ contract passing in the contract address as the first parameter like this: IENS.store_name(contract_address, _name); ``` -Note that Interfaces excludes the function body/logic and the implicit +Note that Interfaces exclude the function body/logic and the implicit arguments. ### 9. Recursions -Due to the unavailability of loops, Recursions are the go-to for similar +Due to the unavailability of loops, Recursion is the go-to for similar operations. In simple terms, a recursive function is one which calls itself repeatedly. @@ -494,25 +494,25 @@ fibonacci number: ```cairo @external func fibonacci{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}(n : felt) -> (result : felt){ - alloc_locals; - if (n == 0){ - return (0); - } - if (n == 1){ - return (1); - } - let (local x) = fibonacci(n - 1); - let (local y) = fibonacci(n - 2); - return (result=(x + y)); +range_check_ptr}(n : felt) -> (result : felt){ + alloc_locals; + if (n == 0){ + return (0); + } + if (n == 1){ + return (1); } + let (local x) = fibonacci(n - 1); + let (local y) = fibonacci(n - 2); + return (result=(x + y)); +} ``` The nth fibonacci term is the sum of the `nth - 1` and the `nth - 2` numbers, that's why we get these two as `(x,y)` using recursion. NB: when implementing recursive functions, always remember to implement a base -case (`n==0`, `n==1` in our case), to prevent stack overflow. +case (`n==0`, `n==1` in our case), to prevent stack overflows. ### 10. Registers @@ -529,8 +529,8 @@ registers: ### 11. Revoked References -Revoked references occurs when there is a call instruction to another function, -between the definition of a reference variable that depends on `ap`(temp +Revoked references occur when there is a call instruction to another function, +between the definition of a reference variable that depends on `ap` (temp variables) and its usage. This occurs as the compiler may not be able to compute the change of `ap` (as one may jump to the label from another place in the program, or call a function that might change ap in an unknown way). @@ -540,18 +540,18 @@ Here is an example to demonstrate what I mean: ```cairo @external func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}() -> (res: felt) { - return (res=100); - } +range_check_ptr}() -> (res: felt) { + return (res=100); +} @external func double_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}() -> (res: felt) { - let multiplier = 2; - let (balance) = get_balance(); - let new_balance = balance * multiplier; - return (res=new_balance); - } +range_check_ptr}() -> (res: felt) { + let multiplier = 2; + let (balance) = get_balance(); + let new_balance = balance * multiplier; + return (res=new_balance); +} ``` If you run that code, you'll run into the revoked reference error as we are @@ -559,20 +559,20 @@ trying to access the `multiplier` variable after calling the `get_balance` function. In simple cases you can resolve revoked references by adding the keyword -`alloc_locals` within function scopes. In most complex cases you might need to +`alloc_locals` within function scopes. In more complex cases you might need to create a local variable to resolve it. ```cairo // resolving the `double_balance` function: @external func double_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}() -> (res: felt) { - alloc_locals; - let multiplier = 2; - let (balance) = get_balance(); - let new_balance = balance * multiplier; - return (res=new_balance); - } +range_check_ptr}() -> (res: felt) { + alloc_locals; + let multiplier = 2; + let (balance) = get_balance(); + let new_balance = balance * multiplier; + return (res=new_balance); +} ``` ### 12. Understanding Cairo's Punctuations @@ -627,7 +627,7 @@ const ACCOUNT_BALANCE_BOUND = 1073741; // (2 ** 30 / 1000) // // @dev A map from account and token type to corresponding balance @storage_var -func account_balance(account_id: felt, token_type: felt) -> (balance: felt){} +func account_balance(account_id: felt, token_type: felt) -> (balance: felt) {} // @dev a map from token type to corresponding pool balance @storage_var @@ -641,21 +641,21 @@ func pool_balance(token_type: felt) -> (balance: felt) {} // @param token_type Token to be queried @view func get_account_token_balance{syscall_ptr: felt*, pedersen_ptr: - HashBuiltin*, range_check_ptr}( - account_id: felt, token_type: felt - ) -> (balance: felt) { - return account_balance.read(account_id, token_type); - } +HashBuiltin*, range_check_ptr}( + account_id: felt, token_type: felt + ) -> (balance: felt) { + return account_balance.read(account_id, token_type); +} // @dev return the pool's balance // @param token_type Token type to get pool balance @view func get_pool_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}( - token_type: felt - ) -> (balance: felt) { - return pool_balance.read(token_type); - } +range_check_ptr}( + token_type: felt + ) -> (balance: felt) { + return pool_balance.read(token_type); +} // EXTERNALS @@ -665,55 +665,55 @@ func get_pool_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, // @param balance Amount to be set as balance @external func set_pool_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}( - token_type: felt, balance: felt - ) { - with_attr error_message("exceeds maximum allowed tokens!"){ - assert_nn_le(balance, BALANCE_UPPER_BOUND - 1); - } +range_check_ptr}( + token_type: felt, balance: felt + ) { + with_attr error_message("exceeds maximum allowed tokens!"){ + assert_nn_le(balance, BALANCE_UPPER_BOUND - 1); + } pool_balance.write(token_type, balance); return (); - } +} // @dev add demo token to the given account // @param token_a_amount amount of token a to be added // @param token_b_amount amount of token b to be added @external func add_demo_token{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}( +range_check_ptr}( token_a_amount: felt, token_b_amount: felt ) { - alloc_locals; - let (account_id) = get_caller_address(); + alloc_locals; + let (account_id) = get_caller_address(); - modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_A, - amount=token_a_amount); - modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_B, - amount=token_b_amount); + modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_A, + amount=token_a_amount); + modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_B, + amount=token_b_amount); - return (); - } + return (); +} // @dev intialize AMM // @param token_a amount of token a to be set in pool // @param token_b amount of token b to be set in pool @external func init_pool{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}( - token_a: felt, token_b: felt - ) { - with_attr error_message("exceeds maximum allowed tokens!"){ - assert_nn_le(token_a, POOL_UPPER_BOUND - 1); - assert_nn_le(token_b, POOL_UPPER_BOUND - 1); - } - - set_pool_token_balance(token_type=TOKEN_TYPE_A, balance=token_a); - set_pool_token_balance(token_type=TOKEN_TYPE_B, balance=token_b); - - return (); +range_check_ptr}( + token_a: felt, token_b: felt + ) { + with_attr error_message("exceeds maximum allowed tokens!"){ + assert_nn_le(token_a, POOL_UPPER_BOUND - 1); + assert_nn_le(token_b, POOL_UPPER_BOUND - 1); } + set_pool_token_balance(token_type=TOKEN_TYPE_A, balance=token_a); + set_pool_token_balance(token_type=TOKEN_TYPE_B, balance=token_b); + + return (); +} + // @dev swaps token between the given account and the pool // @param token_from token to be swapped @@ -723,32 +723,32 @@ func init_pool{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, func swap{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( token_from: felt, amount_from: felt ) -> (amount_to: felt) { - alloc_locals; - let (account_id) = get_caller_address(); - - // verify token_from is TOKEN_TYPE_A or TOKEN_TYPE_B - with_attr error_message("token not allowed in pool!"){ - assert (token_from - TOKEN_TYPE_A) * (token_from - TOKEN_TYPE_B) = 0; - } - - // check requested amount_from is valid - with_attr error_message("exceeds maximum allowed tokens!"){ - assert_nn_le(amount_from, BALANCE_UPPER_BOUND - 1); - } - - // check user has enough funds - let (account_from_balance) = - get_account_token_balance(account_id=account_id, token_type=token_from); - with_attr error_message("insufficient balance!"){ - assert_le(amount_from, account_from_balance); - } - - let (token_to) = get_opposite_token(token_type=token_from); - let (amount_to) = do_swap(account_id=account_id, token_from=token_from, - token_to=token_to, amount_from=amount_from); - - return (amount_to=amount_to); - } + alloc_locals; + let (account_id) = get_caller_address(); + + // verify token_from is TOKEN_TYPE_A or TOKEN_TYPE_B + with_attr error_message("token not allowed in pool!"){ + assert (token_from - TOKEN_TYPE_A) * (token_from - TOKEN_TYPE_B) = 0; + } + + // check requested amount_from is valid + with_attr error_message("exceeds maximum allowed tokens!"){ + assert_nn_le(amount_from, BALANCE_UPPER_BOUND - 1); + } + + // check user has enough funds + let (account_from_balance) = + get_account_token_balance(account_id=account_id, token_type=token_from); + with_attr error_message("insufficient balance!"){ + assert_le(amount_from, account_from_balance); + } + + let (token_to) = get_opposite_token(token_type=token_from); + let (amount_to) = do_swap(account_id=account_id, token_from=token_from, + token_to=token_to, amount_from=amount_from); + + return (amount_to=amount_to); +} // INTERNALS @@ -761,17 +761,17 @@ func modify_account_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( account_id: felt, token_type: felt, amount: felt ) { - let (current_balance) = account_balance.read(account_id, token_type); - tempvar new_balance = current_balance + amount; + let (current_balance) = account_balance.read(account_id, token_type); + tempvar new_balance = current_balance + amount; - with_attr error_message("exceeds maximum allowed tokens!"){ - assert_nn_le(new_balance, BALANCE_UPPER_BOUND - 1); - } + with_attr error_message("exceeds maximum allowed tokens!"){ + assert_nn_le(new_balance, BALANCE_UPPER_BOUND - 1); + } - account_balance.write(account_id=account_id, token_type=token_type, - value=new_balance); - return (); - } + account_balance.write(account_id=account_id, token_type=token_type, + value=new_balance); + return (); +} // @dev internal function that swaps tokens between the given account and // the pool @@ -783,31 +783,31 @@ func do_swap{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( account_id: felt, token_from: felt, token_to: felt, amount_from: felt ) -> (amount_to: felt) { - alloc_locals; - - // get pool balance - let (local amm_from_balance) = get_pool_token_balance(token_type = - token_from); - let (local amm_to_balance) = get_pool_token_balance(token_type=token_to); - - // calculate swap amount - let (local amount_to, _) = unsigned_div_rem((amm_to_balance * - amount_from), (amm_from_balance + amount_from)); - - // update token_from balances - modify_account_balance(account_id=account_id, token_type=token_from, - amount=-amount_from); - set_pool_token_balance(token_type=token_from, balance=(amm_from_balance - + amount_from)); - - // update token_to balances - modify_account_balance(account_id=account_id, token_type=token_to, - amount=amount_to); - set_pool_token_balance(token_type=token_to, balance=(amm_to_balance - - amount_to)); - - return (amount_to=amount_to); - } + alloc_locals; + + // get pool balance + let (local amm_from_balance) = get_pool_token_balance(token_type = + token_from); + let (local amm_to_balance) = get_pool_token_balance(token_type=token_to); + + // calculate swap amount + let (local amount_to, _) = unsigned_div_rem((amm_to_balance * + amount_from), (amm_from_balance + amount_from)); + + // update token_from balances + modify_account_balance(account_id=account_id, token_type=token_from, + amount=-amount_from); + set_pool_token_balance(token_type=token_from, balance=(amm_from_balance + + amount_from)); + + // update token_to balances + modify_account_balance(account_id=account_id, token_type=token_to, + amount=amount_to); + set_pool_token_balance(token_type=token_to, balance=(amm_to_balance - + amount_to)); + + return (amount_to=amount_to); +} // @dev internal function to get the opposite token type -- cgit v1.2.3 From b83fe079a2c8cce4091e04cf6669019b0c886485 Mon Sep 17 00:00:00 2001 From: Darlington02 Date: Mon, 6 Feb 2023 15:10:30 +0100 Subject: made function patterns consistent --- cairo.html.markdown | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/cairo.html.markdown b/cairo.html.markdown index e6a04b67..69d6ba2b 100644 --- a/cairo.html.markdown +++ b/cairo.html.markdown @@ -157,14 +157,16 @@ from starkware.cairo.common.cairo_builtins import HashBuiltin // @storage_var is a decorator that instructs the compiler the function // below it is a storage variable. @storage_var -func balance() -> (res: felt){} +func balance() -> (res: felt) {} // @dev Constructor writes the balance variable to 0 on deployment // Constructors sets storage variables on deployment. Can accept arguments too. @constructor func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}() {balance.write(0); return(); - } +range_check_ptr}() { + balance.write(0); + return(); +} // @dev increase_balance updates the balance variable // @param amount the amount you want to add to balance @@ -172,23 +174,23 @@ func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, // function. @external func increase_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}(amount: felt){ - with_attr error_message("Amount must be positive. Got: {amount}.") { - assert_nn(amount); - } +range_check_ptr}(amount: felt){ + with_attr error_message("Amount must be positive. Got: {amount}.") { + assert_nn(amount); + } - let (res) = balance.read(); - balance.write(res + amount); - return (); + let (res) = balance.read(); + balance.write(res + amount); + return (); } // @dev returns the balance variable // @view is a decorator that specifies the func below it is a view function. @view func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, - range_check_ptr}() -> (res: felt) { - let (res) = balance.read(); - return (res,); +range_check_ptr}() -> (res: felt) { + let (res) = balance.read(); + return (res,); } ``` @@ -449,7 +451,7 @@ const ADMIN = 0x01C6cfC1DB2ae90dACEA243F0a8C2F4e32560F7cDD398e4dA2Cc56B733774E9b with_attr error_message("You do not have access to make this action!"){ let (caller) = get_caller_address(); assert ADMIN = caller; - } +} // using an assert statement throws if condition is not true, thus // returning the specified error. @@ -810,15 +812,15 @@ range_check_ptr}( } - // @dev internal function to get the opposite token type - // @param token_type Token whose opposite pair needs to be gotten - func get_opposite_token(token_type: felt) -> (t: felt) { - if(token_type == TOKEN_TYPE_A) { - return (t=TOKEN_TYPE_B); - } else { - return (t=TOKEN_TYPE_A); - } +// @dev internal function to get the opposite token type +// @param token_type Token whose opposite pair needs to be gotten +func get_opposite_token(token_type: felt) -> (t: felt) { + if(token_type == TOKEN_TYPE_A) { + return (t=TOKEN_TYPE_B); + } else { + return (t=TOKEN_TYPE_A); } +} ``` ## Additional Resources -- cgit v1.2.3 From 97806f674f78b9adffb51127039d98b02a666e60 Mon Sep 17 00:00:00 2001 From: John Paul Wohlscheid Date: Wed, 15 Feb 2023 13:26:47 -0500 Subject: removed tutorial that no longer exists --- python.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python.html.markdown b/python.html.markdown index 175f17ec..c157750f 100644 --- a/python.html.markdown +++ b/python.html.markdown @@ -10,6 +10,7 @@ contributors: - ["Roberto Fernandez Diaz", "https://github.com/robertofd1995"] - ["caminsha", "https://github.com/caminsha"] - ["Stanislav Modrak", "https://stanislav.gq"] + - ["John Paul Wohlscheid", "https://gitpi.us"] filename: learnpython.py --- @@ -1045,7 +1046,6 @@ print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :( ### Free Online * [Automate the Boring Stuff with Python](https://automatetheboringstuff.com) -* [Ideas for Python Projects](http://pythonpracticeprojects.com) * [The Official Docs](https://docs.python.org/3/) * [Hitchhiker's Guide to Python](https://docs.python-guide.org/en/latest/) * [Python Course](https://www.python-course.eu) -- cgit v1.2.3 From 5d44b4ac331ed5ccc5145a26b5681b587ebee442 Mon Sep 17 00:00:00 2001 From: rilysh Date: Thu, 16 Feb 2023 10:21:31 +0530 Subject: add: several docs & online interpreter url --- bf.html.markdown | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bf.html.markdown b/bf.html.markdown index 5ede0546..adc58f02 100644 --- a/bf.html.markdown +++ b/bf.html.markdown @@ -4,12 +4,13 @@ filename: bf.bf contributors: - ["Prajit Ramachandran", "http://prajitr.github.io/"] - ["Mathias Bynens", "http://mathiasbynens.be/"] + - ["rilysh", "https://github.com/rilysh"] --- Brainfuck (not capitalized except at the start of a sentence) is an extremely minimal Turing-complete programming language with just 8 commands. -You can try brainfuck on your browser with [brainfuck-visualizer](https://brainfuck-visualizer.herokuapp.com). +You can try brainfuck on your browser with [brainfuck-online](https://copy.sh/brainfuck/). ```bf Any character not "><+-.,[]" (excluding quotation marks) is ignored. @@ -80,3 +81,8 @@ And that's brainfuck. Not that hard, eh? For fun, you can write your own brainfuck programs, or you can write a brainfuck interpreter in another language. The interpreter is fairly simple to implement, but if you're a masochist, try writing a brainfuck interpreter… in brainfuck. + +## Further Reading + * [esolang-wiki](https://esolangs.org/wiki/Brainfuck) + * [learn brainfuck](http://cydathria.com/bf/brainfuck.html) + * [other resources](http://www.muppetlabs.com/~breadbox/bf/) -- cgit v1.2.3 From c3cc321c31ffdf8a5bba68842c7e74bbc7ae3439 Mon Sep 17 00:00:00 2001 From: Xianguang Zhou Date: Fri, 17 Feb 2023 17:54:37 +0800 Subject: [clojure-macros/zh-cn] Delete a unmatched parenthesis. (#4599) --- zh-cn/clojure-macro-cn.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zh-cn/clojure-macro-cn.html.markdown b/zh-cn/clojure-macro-cn.html.markdown index 23b2f203..85b966e9 100644 --- a/zh-cn/clojure-macro-cn.html.markdown +++ b/zh-cn/clojure-macro-cn.html.markdown @@ -131,7 +131,7 @@ lang: zh-cn ; 然而,如果我们希望它在编译期执行,就需要创建宏 (defmacro inline-2 [form] - (inline-2-helper form))) + (inline-2-helper form)) (macroexpand '(inline-2 (1 + (3 / 2) - (1 / 2) + 1))) ; -> (+ (- (+ 1 (/ 3 2)) (/ 1 2)) 1) -- cgit v1.2.3 From 2b4c8854bfb1034983a228ba6ba098c0f5320d2e Mon Sep 17 00:00:00 2001 From: Stanislaw Baranski Date: Thu, 23 Feb 2023 19:27:00 +0100 Subject: Add the vertical bar qualifier explanation The vertical bar qualifier explanation is missing, but it's widely used interchangeably with the colon qualifier. Even it the text you use "|" so it should be explained as well. --- set-theory.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/set-theory.html.markdown b/set-theory.html.markdown index d55ab7d5..f89345c0 100644 --- a/set-theory.html.markdown +++ b/set-theory.html.markdown @@ -17,7 +17,7 @@ Set theory is a branch of mathematics that studies sets, their operations, and t * the cross operator, `×`, means "the Cartesian product of". ### Qualifiers -* the colon qualifier, `:`, means "such that"; +* the colon, `:`, or the vertical bar `|` qualifiers are interchangeable and mean "such that"; * the membership qualifier, `∈`, means "belongs to"; * the subset qualifier, `⊆`, means "is a subset of"; * the proper subset qualifier, `⊂`, means "is a subset of but is not equal to". -- cgit v1.2.3 From 54ac222de000fa48272187e2c469c6b7b742e511 Mon Sep 17 00:00:00 2001 From: Marcel Ribeiro-Dantas Date: Tue, 28 Feb 2023 11:40:48 -0300 Subject: Add correct indentation to cairo's header Signed-off-by: Marcel Ribeiro-Dantas --- cairo.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cairo.html.markdown b/cairo.html.markdown index 69d6ba2b..faad304a 100644 --- a/cairo.html.markdown +++ b/cairo.html.markdown @@ -2,7 +2,7 @@ language: Cairo filename: learnCairo.sol contributors: - - ["Darlington Nnam", "https://github.com/Darlington02"] + - ["Darlington Nnam", "https://github.com/Darlington02"] --- # Cairo -- cgit v1.2.3 From c8aa954518d119108ea974691f6eab0fce9c1c20 Mon Sep 17 00:00:00 2001 From: Marcel Ribeiro-Dantas Date: Tue, 28 Feb 2023 11:42:36 -0300 Subject: Remove cairo syntax highlighting in cairo's docs Signed-off-by: Marcel Ribeiro-Dantas --- cairo.html.markdown | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/cairo.html.markdown b/cairo.html.markdown index faad304a..dd3ca036 100644 --- a/cairo.html.markdown +++ b/cairo.html.markdown @@ -145,7 +145,7 @@ sequence: First let's look at a default contract that comes with Protostar which allows you to set balance on deployment, increase, and get the balance. -```cairo +``` // Language directive - instructs compiler its a StarkNet contract %lang starknet @@ -205,7 +205,7 @@ just a single data type `..felts`. Felts stands for Field elements, and are a 252 bit integer in the range `0<=x<=P` where `P` is a prime number. You can create a `Uint256` in Cairo by utlizing a struct of two 128 bits felts. -```cairo +``` struct Uint256 { low: felt, // The low 128 bits of the value. high: felt, // The high 128 bits of the value. @@ -219,7 +219,7 @@ To avoid running into issues with divisions, it's safer to work with the To get started with writing a StarkNet contract, you must specify the directive: -```cairo +``` %lang starknet ``` @@ -230,7 +230,7 @@ storage, programs don't and as such are stateless. There are important functions you might need to import from the official Cairo-lang library or Openzeppelin's, e.g. -```cairo +``` from starkware.cairo.common.cairo_builtins import HashBuiltin from cairo_contracts.src.openzeppelin.token.erc20.library import ERC20 from starkware.cairo.common.uint256 import Uint256 @@ -243,7 +243,7 @@ from starkware.cairo.common.bool import TRUE slot is a felt which is initialized to `0`. You create one using the `@storage_var` decorator. - ```cairo + ``` @storage_var func names() -> (name: felt) {} ``` @@ -251,7 +251,7 @@ from starkware.cairo.common.bool import TRUE + Storage mappings: Unlike Solidity where mappings have a separate keyword, in Cairo you create mappings using storage variables. - ```cairo + ``` @storage_var func names(address: felt) -> (name: felt) {} ``` @@ -261,7 +261,7 @@ from starkware.cairo.common.bool import TRUE retrieved using `MyStruct.SIZE`. You create a struct in Cairo using the `struct` keyword. - ```cairo + ``` struct Person { name: felt, age: felt, @@ -274,7 +274,7 @@ from starkware.cairo.common.bool import TRUE constant in Cairo, you use the `const` keyword. It's proper practice to capitalize constant names. - ```cairo + ``` const USER = 0x01C6cfC1DB2ae90dACEA243F0a8C2F4e32560F7cDD398e4dA2Cc56B733774E9b ``` @@ -283,7 +283,7 @@ from starkware.cairo.common.bool import TRUE cells. The `alloc` keyword can be used to dynamically allocate a new memory segment, which can be used to store an array: - ```cairo + ``` let (myArray: felt*) = alloc (); assert myArray[0] = 1; assert myArray[1] = 2; @@ -294,7 +294,7 @@ from starkware.cairo.common.bool import TRUE tuples. The new operator is useful as it enables you allocate memory and initialize the object in one instruction - ```cairo + ``` func foo() { tempvar arr: felt* = new (1, 1, 2, 3, 5); assert arr[4] = 5; @@ -306,7 +306,7 @@ from starkware.cairo.common.bool import TRUE represented as a comma-separated list of elements enclosed by parentheses. Their elements may be of any combination of valid types. - ```cairo + ``` local tuple0: (felt, felt, felt) = (7, 9, 13); ``` @@ -314,7 +314,7 @@ from starkware.cairo.common.bool import TRUE execution, that can be used outside of StarkNet. An event can be created, subsequently emitted: - ```cairo + ``` @event func name_stored(address, name) {} @@ -327,7 +327,7 @@ from starkware.cairo.common.bool import TRUE contract deployment. You create a constructor using the `@constructor` decorator. - ```cairo + ``` @constructor func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(_name: felt) { @@ -341,7 +341,7 @@ from starkware.cairo.common.bool import TRUE of the network. You create an external function using the `@external` decorator: - ```cairo + ``` @external func store_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(_name: felt){ @@ -355,7 +355,7 @@ from starkware.cairo.common.bool import TRUE + View functions: View functions do not modify the state of the blockchain. You can create a view function using the `@view` decorator. - ```cairo + ``` @view func get_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(_address: felt) -> (name: felt){ @@ -413,7 +413,7 @@ Here are the most common decorators you'll encounter in Cairo: you can in your contracts, as hints are not added to the bytecode, and thus do not count in the total number of execution steps. - ```cairo + ``` %{ # Python hint goes here %} @@ -423,7 +423,7 @@ Here are the most common decorators you'll encounter in Cairo: inherited by other functions calls that require them. Implicit arguments are passed in between curly bracelets, like you can see below: - ```cairo + ``` func store_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(_name: felt){ let (caller) = get_caller_address(); @@ -440,7 +440,7 @@ execution. This can be very useful for implementing checks and proper access control mechanisms. An example is preventing a user to call a function except user is `admin`. -```cairo +``` // imports from starkware.starknet.common.syscalls import get_caller_address @@ -463,7 +463,7 @@ Contract interfaces provide a means for one contract to invoke or call the external function of another contract. To create a contract interface, you use the `@contract_interface` keyword: -```cairo +``` @contract_interface namespace IENS { func store_name(_name: felt) { @@ -477,7 +477,7 @@ the `@contract_interface` keyword: Once a contract interface is specified, any contract can make calls to that contract passing in the contract address as the first parameter like this: -```cairo +``` IENS.store_name(contract_address, _name); ``` @@ -493,7 +493,7 @@ repeatedly. A good example to demonstrate this is writing a function for getting the nth fibonacci number: -```cairo +``` @external func fibonacci{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(n : felt) -> (result : felt){ @@ -539,7 +539,7 @@ program, or call a function that might change ap in an unknown way). Here is an example to demonstrate what I mean: -```cairo +``` @external func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (res: felt) { @@ -564,7 +564,7 @@ In simple cases you can resolve revoked references by adding the keyword `alloc_locals` within function scopes. In more complex cases you might need to create a local variable to resolve it. -```cairo +``` // resolving the `double_balance` function: @external func double_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, @@ -600,7 +600,7 @@ range_check_ptr}() -> (res: felt) { Below is a simple automated market maker contract example that implements most of what we just learnt! Re-write, deploy, have fun! -```cairo +``` %lang starknet from starkware.cairo.common.cairo_builtins import HashBuiltin -- cgit v1.2.3 From fbaa905e23f26d20b37a3886dd8e07cd6edb8680 Mon Sep 17 00:00:00 2001 From: Marcel Ribeiro-Dantas Date: Tue, 28 Feb 2023 21:00:37 -0300 Subject: Fix broken pages due to unknown language for syntax highlighting Signed-off-by: Marcel Ribeiro-Dantas --- hjson.html.markdown | 2 +- lbstanza.html.markdown | 6 +++--- openscad.html.markdown | 2 +- zig.html.markdown | 52 +++++++++++++++++++++++++------------------------- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/hjson.html.markdown b/hjson.html.markdown index b9b35062..6b3cc3ed 100644 --- a/hjson.html.markdown +++ b/hjson.html.markdown @@ -15,7 +15,7 @@ to read and edit before passing the JSON data to the machine. Let's take a look at examples to see the key syntax differences! -```hjson +``` { # Comments are totally supported! diff --git a/lbstanza.html.markdown b/lbstanza.html.markdown index 06a38aef..90e7b7e5 100644 --- a/lbstanza.html.markdown +++ b/lbstanza.html.markdown @@ -8,7 +8,7 @@ contributors: LB Stanza (or Stanza for short) is a new optionally-typed general purpose programming language from the University of California, Berkeley. Stanza was designed to help programmers tackle the complexity of architecting large programs and significantly increase the productivity of application programmers across the entire software development life cycle. -```stanza +``` ; this is a comment ; This is a block comment @@ -268,7 +268,7 @@ is-there = any?({_ == 2.0}, numbers) doc: \ # Document Strings - ```stanza + ``` val you-can = "include code snippets, too" ``` @@ -279,4 +279,4 @@ doc: \ ``` \ defn docfn () : false -``` \ No newline at end of file +``` diff --git a/openscad.html.markdown b/openscad.html.markdown index e09b5109..63570cbe 100644 --- a/openscad.html.markdown +++ b/openscad.html.markdown @@ -7,7 +7,7 @@ contributors: Draw 3D models with code using [OpenSCAD](https://openscad.org/). -```openscad +``` // Comments look like this // 3D Primitives diff --git a/zig.html.markdown b/zig.html.markdown index 82c6b994..f8c866e5 100644 --- a/zig.html.markdown +++ b/zig.html.markdown @@ -39,7 +39,7 @@ Prior knowledge of C is recommended. ## Zig language -```zig +``` //! Top-level documentation. /// Documentation comment. @@ -49,7 +49,7 @@ Prior knowledge of C is recommended. ### Hello world. -```zig +``` // Import standard library, reachable through the "std" constant. const std = @import("std"); @@ -67,7 +67,7 @@ pub fn main() void { ``` ### Booleans, integers and float. -```zig +``` // Booleans. // Keywords are preferred to operators for boolean operations. print("{}\n{}\n{}\n", .{ @@ -109,7 +109,7 @@ i <<| 8 == 255 // u8: won't go higher than 255 ``` ### Arrays. -```zig +``` // An array is a well-defined structure with a length attribute (len). // 5-byte array with undefined content (stack garbage). @@ -156,7 +156,7 @@ try some_integers[i]; // Runtime error 'index out of bounds'. ``` ### Multidimensional arrays. -```zig +``` const mat4x4 = [4][4]f32{ [_]f32{ 1.0, 0.0, 0.0, 0.0 }, @@ -177,7 +177,7 @@ for (mat4x4) |row, row_index| { ``` ### Strings. -```zig +``` // Simple string constant. const greetings = "hello"; @@ -195,7 +195,7 @@ print("string: {s}\n", .{greetings}); ``` ### Slices. -```zig +``` // A slice is a pointer and a size, an array without compile-time known size. // Slices have runtime out-of-band verifications. @@ -206,7 +206,7 @@ const slice = array[0..array.len]; // "slice" represents the whole array. ``` ### Pointers. -```zig +``` // Pointer on a value can be created with "&". const x: i32 = 1; @@ -223,7 +223,7 @@ const foo = pointer.?; // Get the pointed value, otherwise crash. ``` ### Optional values (?). -```zig +``` // An optional is a value than can be of any type or null. // Example: "optional_value" can either be "null" or an unsigned 32-bit integer. @@ -239,7 +239,7 @@ if (x) |value| { ``` ### Errors. -```zig +``` // Zig provides an unified way to express errors. // Errors are defined in error enumerations, example: @@ -299,7 +299,7 @@ var value = try some_function(); ### Control flow. -```zig +``` // Conditional branching. if (condition) { @@ -384,7 +384,7 @@ const result = for (items) |value| { ``` ### Labels. -```zig +``` // Labels are a way to name an instruction, a location in the code. // Labels can be used to "continue" or "break" in a nested loop. @@ -434,7 +434,7 @@ const result = for (items) |value| { // First: loop. ``` ### Switch. -```zig +``` // As a switch in C, but slightly more advanced. // Syntax: @@ -461,7 +461,7 @@ const bar = switch (foo) { ``` ### Structures. -```zig +``` // Structure containing a single value. const Full = struct { @@ -564,7 +564,7 @@ print("p.y: {}\n", .{p.y}); // 30 ``` ### Tuples. -```zig +``` // A tuple is a list of elements, possibly of different types. const foo = .{ "hello", true, 42 }; @@ -572,7 +572,7 @@ const foo = .{ "hello", true, 42 }; ``` ### Enumerations. -```zig +``` const Type = enum { ok, not_ok }; @@ -606,7 +606,7 @@ const x = switch (direction) { ``` ### Unions. -```zig +``` const Bar = union { boolean: bool, @@ -622,7 +622,7 @@ const foo: Bar = .{ .int = 42 }; ``` ### Tagged unions. -```zig +``` // Unions can be declared with an enum tag type, allowing them to be used in // switch expressions. @@ -653,7 +653,7 @@ switch (nay) { ``` ### Defer and errdefer. -```zig +``` // Make sure that an action (single instruction or block of code) is executed // before the end of the scope (function, block of code). @@ -712,7 +712,7 @@ However, here are some examples, to get an idea of what you can expect: Very simple way of avoiding leaks. A first example. -```zig +``` // "!void" means the function doesn't return any value except for errors. // In this case we try to allocate memory, and this may fail. fn foo() !void { @@ -735,7 +735,7 @@ fn foo() !void { ``` ### Memory allocation combined with error management and defer. -```zig +``` fn some_memory_allocation_example() !void { // Memory allocation may fail, so we "try" to allocate the memory and @@ -759,7 +759,7 @@ fn some_memory_allocation_example() !void { ``` ### Memory allocators: a taste of the standard library. -```zig +``` // Allocators: 4 main functions to know // single_value = create (type) @@ -846,7 +846,7 @@ fn gpa_arena_allocator_fn() !void { ``` ### Comptime. -```zig +``` // Comptime is a way to avoid the pre-processor. // The idea is simple: run code at compilation. @@ -883,7 +883,7 @@ list.items[0] = 10; ``` ### Conditional compilation. -```zig +``` const available_os = enum { OpenBSD, Linux }; const myos = available_os.OpenBSD; @@ -905,7 +905,7 @@ const myprint = switch(myos) { ``` ### Testing our functions. -```zig +``` const std = @import("std"); const expect = std.testing.expect; @@ -936,7 +936,7 @@ There are more than a hundred built-ins, allowing very low-level stuff: - etc. Example: enums aren't integers, they have to be converted with a built-in. -```zig +``` const Value = enum { zero, stuff, blah }; if (@enumToInt(Value.zero) == 0) { ... } if (@enumToInt(Value.stuff) == 1) { ... } -- cgit v1.2.3