Merge remote-tracking branch 'upstream/master'

Conflicts:
	perl6.html.markdown
This commit is contained in:
Jonathan Scott Duff 2015-06-25 22:58:56 -05:00
commit 2162639cd9
37 changed files with 4419 additions and 347 deletions

View File

@ -10,6 +10,7 @@ contributors:
- ["Anton Strömkvist", "http://lutic.org/"] - ["Anton Strömkvist", "http://lutic.org/"]
- ["Rahil Momin", "https://github.com/iamrahil"] - ["Rahil Momin", "https://github.com/iamrahil"]
- ["Gregrory Kielian", "https://github.com/gskielian"] - ["Gregrory Kielian", "https://github.com/gskielian"]
- ["Etan Reisner", "https://github.com/deryni"]
filename: LearnBash.sh filename: LearnBash.sh
--- ---
@ -31,32 +32,41 @@ echo Hello world!
echo 'This is the first line'; echo 'This is the second line' echo 'This is the first line'; echo 'This is the second line'
# Declaring a variable looks like this: # Declaring a variable looks like this:
VARIABLE="Some string" Variable="Some string"
# But not like this: # But not like this:
VARIABLE = "Some string" Variable = "Some string"
# Bash will decide that VARIABLE is a command it must execute and give an error # Bash will decide that Variable is a command it must execute and give an error
# because it couldn't be found. # because it can't be found.
# Or like this:
Variable= 'Some string'
# 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: # Using the variable:
echo $VARIABLE echo $Variable
echo "$VARIABLE" echo "$Variable"
echo '$VARIABLE' echo '$Variable'
# When you use the variable itself — assign it, export it, or else — you write # When you use the variable itself — assign it, export it, or else — you write
# its name without $. If you want to use variable's value, you should use $. # its name without $. If you want to use variable's value, you should use $.
# Note that ' (single quote) won't expand the variables! # Note that ' (single quote) won't expand the variables!
# String substitution in variables # String substitution in variables
echo ${VARIABLE/Some/A} echo ${Variable/Some/A}
# This will substitute the first occurance of "Some" with "A" # This will substitute the first occurrence of "Some" with "A"
# Substring from a variable # Substring from a variable
echo ${VARIABLE:0:7} Length=7
echo ${Variable:0:Length}
# This will return only the first 7 characters of the value # This will return only the first 7 characters of the value
# Default value for variable # Default value for variable
echo ${FOO:-"DefaultValueIfFOOIsMissingOrEmpty"} echo ${Foo:-"DefaultValueIfFooIsMissingOrEmpty"}
# This works for null (FOO=), 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.
# Builtin variables: # Builtin variables:
# There are some useful builtin variables, like # There are some useful builtin variables, like
@ -64,16 +74,16 @@ echo "Last program return value: $?"
echo "Script's PID: $$" echo "Script's PID: $$"
echo "Number of arguments: $#" echo "Number of arguments: $#"
echo "Scripts arguments: $@" echo "Scripts arguments: $@"
echo "Scripts arguments seperated in different variables: $1 $2..." echo "Scripts arguments separated in different variables: $1 $2..."
# Reading a value from input: # Reading a value from input:
echo "What's your name?" echo "What's your name?"
read NAME # Note that we didn't need to declare a new variable read Name # Note that we didn't need to declare a new variable
echo Hello, $NAME! echo Hello, $Name!
# We have the usual if structure: # We have the usual if structure:
# use 'man test' for more info about conditionals # use 'man test' for more info about conditionals
if [ $NAME -ne $USER ] if [ $Name -ne $USER ]
then then
echo "Your name isn't your username" echo "Your name isn't your username"
else else
@ -85,14 +95,14 @@ echo "Always executed" || echo "Only executed if first command fails"
echo "Always executed" && echo "Only executed if first command does NOT fail" echo "Always executed" && echo "Only executed if first command does NOT fail"
# To use && and || with if statements, you need multiple pairs of square brackets: # To use && and || with if statements, you need multiple pairs of square brackets:
if [ $NAME == "Steve" ] && [ $AGE -eq 15 ] if [ $Name == "Steve" ] && [ $Age -eq 15 ]
then then
echo "This will run if $NAME is Steve AND $AGE is 15." echo "This will run if $Name is Steve AND $Age is 15."
fi fi
if [ $NAME == "Daniya" ] || [ $NAME == "Zach" ] if [ $Name == "Daniya" ] || [ $Name == "Zach" ]
then then
echo "This will run if $NAME is Daniya OR Zach." echo "This will run if $Name is Daniya OR Zach."
fi fi
# Expressions are denoted with the following format: # Expressions are denoted with the following format:
@ -134,7 +144,7 @@ python hello.py > /dev/null 2>&1
# if you want to append instead, use ">>": # if you want to append instead, use ">>":
python hello.py >> "output.out" 2>> "error.err" python hello.py >> "output.out" 2>> "error.err"
# Overwrite output.txt, append to error.err, and count lines: # Overwrite output.out, append to error.err, and count lines:
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
wc -l output.out error.err wc -l output.out error.err
@ -142,7 +152,7 @@ wc -l output.out error.err
# see: man fd # see: man fd
echo <(echo "#helloworld") echo <(echo "#helloworld")
# Overwrite output.txt with "#helloworld": # Overwrite output.out with "#helloworld":
cat > output.out <(echo "#helloworld") cat > output.out <(echo "#helloworld")
echo "#helloworld" > output.out echo "#helloworld" > output.out
echo "#helloworld" | cat > output.out echo "#helloworld" | cat > output.out
@ -161,7 +171,7 @@ echo "There are $(ls | wc -l) items here."
echo "There are `ls | wc -l` items here." echo "There are `ls | wc -l` items here."
# Bash uses a case statement that works similarly to switch in Java and C++: # Bash uses a case statement that works similarly to switch in Java and C++:
case "$VARIABLE" in case "$Variable" in
#List patterns for the conditions you want to meet #List patterns for the conditions you want to meet
0) echo "There is a zero.";; 0) echo "There is a zero.";;
1) echo "There is a one.";; 1) echo "There is a one.";;
@ -169,10 +179,10 @@ case "$VARIABLE" in
esac esac
# for loops iterate for as many arguments given: # for loops iterate for as many arguments given:
# The contents of $VARIABLE is printed three times. # The contents of $Variable is printed three times.
for VARIABLE in {1..3} for Variable in {1..3}
do do
echo "$VARIABLE" echo "$Variable"
done done
# Or write it the "traditional for loop" way: # Or write it the "traditional for loop" way:
@ -183,16 +193,16 @@ done
# They can also be used to act on files.. # They can also be used to act on files..
# This will run the command 'cat' on file1 and file2 # This will run the command 'cat' on file1 and file2
for VARIABLE in file1 file2 for Variable in file1 file2
do do
cat "$VARIABLE" cat "$Variable"
done done
# ..or the output from a command # ..or the output from a command
# This will cat the output from ls. # This will cat the output from ls.
for OUTPUT in $(ls) for Output in $(ls)
do do
cat "$OUTPUT" cat "$Output"
done done
# while loop: # while loop:
@ -220,7 +230,7 @@ bar ()
} }
# Calling your function # Calling your function
foo "My name is" $NAME foo "My name is" $Name
# There are a lot of useful commands you should learn: # There are a lot of useful commands you should learn:
# prints last 10 lines of file.txt # prints last 10 lines of file.txt

View File

@ -32,8 +32,7 @@ one of the most widely-used programming languages.
// variable declarations, primitive types, and functions. // variable declarations, primitive types, and functions.
// Just like in C, your program's entry point is a function called // Just like in C, your program's entry point is a function called
// main with an integer return type, // main with an integer return type.
// though void main() is also accepted by most compilers (gcc, clang, etc.)
// This value serves as the program's exit status. // This value serves as the program's exit status.
// See http://en.wikipedia.org/wiki/Exit_status for more information. // See http://en.wikipedia.org/wiki/Exit_status for more information.
int main(int argc, char** argv) int main(int argc, char** argv)
@ -289,7 +288,7 @@ public:
// Functions can also be defined inside the class body. // Functions can also be defined inside the class body.
// Functions defined as such are automatically inlined. // Functions defined as such are automatically inlined.
void bark() const { std::cout << name << " barks!\n" } void bark() const { std::cout << name << " barks!\n"; }
// Along with constructors, C++ provides destructors. // Along with constructors, C++ provides destructors.
// These are called when an object is deleted or falls out of scope. // These are called when an object is deleted or falls out of scope.
@ -301,7 +300,7 @@ public:
}; // A semicolon must follow the class definition. }; // A semicolon must follow the class definition.
// Class member functions are usually implemented in .cpp files. // Class member functions are usually implemented in .cpp files.
void Dog::Dog() Dog::Dog()
{ {
std::cout << "A dog has been constructed\n"; std::cout << "A dog has been constructed\n";
} }
@ -324,7 +323,7 @@ void Dog::print() const
std::cout << "Dog is " << name << " and weighs " << weight << "kg\n"; std::cout << "Dog is " << name << " and weighs " << weight << "kg\n";
} }
void Dog::~Dog() Dog::~Dog()
{ {
cout << "Goodbye " << name << "\n"; cout << "Goodbye " << name << "\n";
} }
@ -333,7 +332,7 @@ int main() {
Dog myDog; // prints "A dog has been constructed" Dog myDog; // prints "A dog has been constructed"
myDog.setName("Barkley"); myDog.setName("Barkley");
myDog.setWeight(10); myDog.setWeight(10);
myDog.printDog(); // prints "Dog is Barkley and weighs 10 kg" myDog.print(); // prints "Dog is Barkley and weighs 10 kg"
return 0; return 0;
} // prints "Goodbye Barkley" } // prints "Goodbye Barkley"
@ -342,7 +341,7 @@ int main() {
// This class inherits everything public and protected from the Dog class // This class inherits everything public and protected from the Dog class
class OwnedDog : public Dog { class OwnedDog : public Dog {
void setOwner(const std::string& dogsOwner) void setOwner(const std::string& dogsOwner);
// Override the behavior of the print function for all OwnedDogs. See // Override the behavior of the print function for all OwnedDogs. See
// http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping // http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
@ -426,13 +425,92 @@ int main () {
Point up (0,1); Point up (0,1);
Point right (1,0); Point right (1,0);
// This calls the Point + operator // This calls the Point + operator
// Point up calls the + (function) with right as its paramater // Point up calls the + (function) with right as its parameter
Point result = up + right; Point result = up + right;
// Prints "Result is upright (1,1)" // Prints "Result is upright (1,1)"
cout << "Result is upright (" << result.x << ',' << result.y << ")\n"; cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
return 0; return 0;
} }
/////////////////////
// Templates
/////////////////////
// Templates in C++ are mostly used for generic programming, though they are
// much more powerful than generics constructs in other languages. It also
// supports explicit and partial specialization, functional-style type classes,
// and also it's Turing-complete.
// We start with the kind of generic programming you might be familiar with. To
// define a class or function that takes a type parameter:
template<class T>
class Box {
public:
// In this class, T can be used as any other type.
void insert(const T&) { ... }
};
// During compilation, the compiler actually generates copies of each template
// with parameters substituted, and so the full definition of the class must be
// present at each invocation. This is why you will see template classes defined
// entirely in header files.
// To instantiate a template class on the stack:
Box<int> intBox;
// and you can use it as you would expect:
intBox.insert(123);
// You can, of course, nest templates:
Box<Box<int> > boxOfBox;
boxOfBox.insert(intBox);
// Up until C++11, you must place a space between the two '>'s, otherwise '>>'
// will be parsed as the right shift operator.
// You will sometimes see
// template<typename T>
// instead. The 'class' keyword and 'typename' keyword are _mostly_
// interchangeable in this case. For full explanation, see
// http://en.wikipedia.org/wiki/Typename
// (yes, that keyword has its own Wikipedia page).
// Similarly, a template function:
template<class T>
void barkThreeTimes(const T& input)
{
input.bark();
input.bark();
input.bark();
}
// Notice that nothing is specified about the type parameters here. The compiler
// will generate and then type-check every invocation of the template, so the
// above function works with any type 'T' that has a const 'bark' method!
Dog fluffy;
fluffy.setName("Fluffy")
barkThreeTimes(fluffy); // Prints "Fluffy barks" three times.
// Template parameters don't have to be classes:
template<int Y>
void printMessage() {
cout << "Learn C++ in " << Y << " minutes!" << endl;
}
// And you can explicitly specialize templates for more efficient code. Of
// course, most real-world uses of specialization are not as trivial as this.
// Note that you still need to declare the function (or class) as a template
// even if you explicitly specified all parameters.
template<>
void printMessage<10>() {
cout << "Learn C++ faster in only 10 minutes!" << endl;
}
printMessage<20>(); // Prints "Learn C++ in 20 minutes!"
printMessage<10>(); // Prints "Learn C++ faster in only 10 minutes!"
///////////////////// /////////////////////
// Exception Handling // Exception Handling
///////////////////// /////////////////////
@ -441,12 +519,13 @@ int main () {
// (see http://en.cppreference.com/w/cpp/error/exception) // (see http://en.cppreference.com/w/cpp/error/exception)
// but any type can be thrown an as exception // but any type can be thrown an as exception
#include <exception> #include <exception>
#include <stdexcept>
// All exceptions thrown inside the _try_ block can be caught by subsequent // All exceptions thrown inside the _try_ block can be caught by subsequent
// _catch_ handlers. // _catch_ handlers.
try { try {
// Do not allocate exceptions on the heap using _new_. // Do not allocate exceptions on the heap using _new_.
throw std::exception("A problem occurred"); throw std::runtime_error("A problem occurred");
} }
// Catch exceptions by const reference if they are objects // Catch exceptions by const reference if they are objects
catch (const std::exception& ex) catch (const std::exception& ex)
@ -537,7 +616,7 @@ void doSomethingWithAFile(const char* filename)
{ {
FILE* fh = fopen(filename, "r"); // Open the file in read mode FILE* fh = fopen(filename, "r"); // Open the file in read mode
if (fh == nullptr) if (fh == nullptr)
throw std::exception("Could not open the file."); throw std::runtime_error("Could not open the file.");
try { try {
doSomethingWithTheFile(fh); doSomethingWithTheFile(fh);
@ -586,8 +665,56 @@ void doSomethingWithAFile(const std::string& filename)
// vector (i.e. self-resizing array), hash maps, and so on // vector (i.e. self-resizing array), hash maps, and so on
// all automatically destroy their contents when they fall out of scope. // all automatically destroy their contents when they fall out of scope.
// - Mutexes using lock_guard and unique_lock // - Mutexes using lock_guard and unique_lock
/////////////////////
// Fun stuff
/////////////////////
// Aspects of C++ that may be surprising to newcomers (and even some veterans).
// This section is, unfortunately, wildly incomplete; C++ is one of the easiest
// languages with which to shoot yourself in the foot.
// You can override private methods!
class Foo {
virtual void bar();
};
class FooSub : public Foo {
virtual void bar(); // overrides Foo::bar!
};
// 0 == false == NULL (most of the time)!
bool* pt = new bool;
*pt = 0; // Sets the value points by 'pt' to false.
pt = 0; // Sets 'pt' to the null pointer. Both lines compile without warnings.
// nullptr is supposed to fix some of that issue:
int* pt2 = new int;
*pt2 = nullptr; // Doesn't compile
pt2 = nullptr; // Sets pt2 to null.
// But somehow 'bool' type is an exception (this is to make `if (ptr)` compile).
*pt = nullptr; // This still compiles, even though '*pt' is a bool!
// '=' != '=' != '='!
// Calls Foo::Foo(const Foo&) or some variant copy constructor.
Foo f2;
Foo f1 = f2;
// Calls Foo::Foo(const Foo&) or variant, but only copies the 'Foo' part of
// 'fooSub'. Any extra members of 'fooSub' are discarded. This sometimes
// horrifying behavior is called "object slicing."
FooSub fooSub;
Foo f1 = fooSub;
// Calls Foo::operator=(Foo&) or variant.
Foo f1;
f1 = f2;
``` ```
Futher Reading: Further Reading:
An up-to-date language reference can be found at An up-to-date language reference can be found at
<http://cppreference.com/w/cpp> <http://cppreference.com/w/cpp>

View File

@ -22,7 +22,7 @@ and often automatically.
; Clojure is written in "forms", which are just ; Clojure is written in "forms", which are just
; lists of things inside parentheses, separated by whitespace. ; lists of things inside parentheses, separated by whitespace.
; ;
; The clojure reader assumes that the first thing is a ; The clojure reader assumes that the first thing is a
; function or macro to call, and the rest are arguments. ; function or macro to call, and the rest are arguments.
; The first call in a file should be ns, to set the namespace ; The first call in a file should be ns, to set the namespace

View File

@ -155,8 +155,8 @@ Now, your handlers may utilize query parameters:
```clojure ```clojure
(defroutes myapp (defroutes myapp
(GET "/posts" req (GET "/posts" req
(let [title (get (:params req) "title") (let [title (get (:params req) :title)
author (get (:params req) "author")] author (get (:params req) :author)]
(str "Title: " title ", Author: " author)))) (str "Title: " title ", Author: " author))))
``` ```
@ -165,8 +165,8 @@ Or, for POST and PUT requests, form parameters as well
```clojure ```clojure
(defroutes myapp (defroutes myapp
(POST "/posts" req (POST "/posts" req
(let [title (get (:params req) "title") (let [title (get (:params req) :title)
author (get (:params req) "author")] author (get (:params req) :author)]
(str "Title: " title ", Author: " author)))) (str "Title: " title ", Author: " author))))
``` ```

View File

@ -305,7 +305,7 @@ filename: learn-emacs-lisp.el
(defun boldify-names () (defun boldify-names ()
(switch-to-buffer-other-window "*test*") (switch-to-buffer-other-window "*test*")
(goto-char (point-min)) (goto-char (point-min))
(while (re-search-forward "Bonjour \\([^!]+\\)!" nil 't) (while (re-search-forward "Bonjour \\(.+\\)!" nil 't)
(add-text-properties (match-beginning 1) (add-text-properties (match-beginning 1)
(match-end 1) (match-end 1)
(list 'face 'bold))) (list 'face 'bold)))
@ -318,7 +318,7 @@ filename: learn-emacs-lisp.el
;; The regular expression is "Bonjour \\(.+\\)!" and it reads: ;; The regular expression is "Bonjour \\(.+\\)!" and it reads:
;; the string "Bonjour ", and ;; the string "Bonjour ", and
;; a group of | this is the \\( ... \\) construct ;; a group of | this is the \\( ... \\) construct
;; any character not ! | this is the [^!] ;; any character | this is the .
;; possibly repeated | this is the + ;; possibly repeated | this is the +
;; and the "!" string. ;; and the "!" string.

View File

@ -195,7 +195,7 @@ cond do
"But I will" "But I will"
end end
# It is common to see the last condition equal to `true`, which will always match. # It is common to set the last condition equal to `true`, which will always match.
cond do cond do
1 + 1 == 3 -> 1 + 1 == 3 ->
"I will never be seen" "I will never be seen"

View File

@ -18,7 +18,7 @@ filename: learnerlang.erl
% Periods (`.`) (followed by whitespace) separate entire functions and % Periods (`.`) (followed by whitespace) separate entire functions and
% expressions in the shell. % expressions in the shell.
% Semicolons (`;`) separate clauses. We find clauses in several contexts: % Semicolons (`;`) separate clauses. We find clauses in several contexts:
% function definitions and in `case`, `if`, `try..catch` and `receive` % function definitions and in `case`, `if`, `try..catch`, and `receive`
% expressions. % expressions.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -27,20 +27,20 @@ filename: learnerlang.erl
Num = 42. % All variable names must start with an uppercase letter. Num = 42. % All variable names must start with an uppercase letter.
% Erlang has single assignment variables, if you try to assign a different value % Erlang has single-assignment variables; if you try to assign a different
% to the variable `Num`, youll get an error. % value to the variable `Num`, youll get an error.
Num = 43. % ** exception error: no match of right hand side value 43 Num = 43. % ** exception error: no match of right hand side value 43
% In most languages, `=` denotes an assignment statement. In Erlang, however, % In most languages, `=` denotes an assignment statement. In Erlang, however,
% `=` denotes a pattern matching operation. `Lhs = Rhs` really means this: % `=` denotes a pattern-matching operation. `Lhs = Rhs` really means this:
% evaluate the right side (Rhs), and then match the result against the pattern % evaluate the right side (`Rhs`), and then match the result against the
% on the left side (Lhs). % pattern on the left side (`Lhs`).
Num = 7 * 6. Num = 7 * 6.
% Floating point number. % Floating-point number.
Pi = 3.14159. Pi = 3.14159.
% Atoms, are used to represent different non-numerical constant values. Atoms % Atoms are used to represent different non-numerical constant values. Atoms
% start with lowercase letters, followed by a sequence of alphanumeric % start with lowercase letters, followed by a sequence of alphanumeric
% characters or the underscore (`_`) or at (`@`) sign. % characters or the underscore (`_`) or at (`@`) sign.
Hello = hello. Hello = hello.
@ -53,34 +53,34 @@ AtomWithSpace = 'some atom with space'.
% Tuples are similar to structs in C. % Tuples are similar to structs in C.
Point = {point, 10, 45}. Point = {point, 10, 45}.
% If we want to extract some values from a tuple, we use the pattern matching % If we want to extract some values from a tuple, we use the pattern-matching
% operator `=`. % operator `=`.
{point, X, Y} = Point. % X = 10, Y = 45 {point, X, Y} = Point. % X = 10, Y = 45
% We can use `_` as a placeholder for variables that were not interested in. % We can use `_` as a placeholder for variables that were not interested in.
% The symbol `_` is called an anonymous variable. Unlike regular variables, % The symbol `_` is called an anonymous variable. Unlike regular variables,
% several occurrences of _ in the same pattern dont have to bind to the same % several occurrences of `_` in the same pattern dont have to bind to the
% value. % same value.
Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}. Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.
{_, {_, {_, Who}, _}, _} = Person. % Who = joe {_, {_, {_, Who}, _}, _} = Person. % Who = joe
% We create a list by enclosing the list elements in square brackets and % We create a list by enclosing the list elements in square brackets and
% separating them with commas. % separating them with commas.
% The individual elements of a list can be of any type. % The individual elements of a list can be of any type.
% The first element of a list is the head of the list. If you imagine removing the % The first element of a list is the head of the list. If you imagine removing
% head from the list, whats left is called the tail of the list. % the head from the list, whats left is called the tail of the list.
ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}]. ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}].
% If `T` is a list, then `[H|T]` is also a list, with head `H` and tail `T`. % If `T` is a list, then `[H|T]` is also a list, with head `H` and tail `T`.
% The vertical bar (`|`) separates the head of a list from its tail. % The vertical bar (`|`) separates the head of a list from its tail.
% `[]` is the empty list. % `[]` is the empty list.
% We can extract elements from a list with a pattern matching operation. If we % We can extract elements from a list with a pattern-matching operation. If we
% have a nonempty list `L`, then the expression `[X|Y] = L`, where `X` and `Y` % have a nonempty list `L`, then the expression `[X|Y] = L`, where `X` and `Y`
% are unbound variables, will extract the head of the list into `X` and the tail % are unbound variables, will extract the head of the list into `X` and the tail
% of the list into `Y`. % of the list into `Y`.
[FirstThing|OtherThingsToBuy] = ThingsToBuy. [FirstThing|OtherThingsToBuy] = ThingsToBuy.
% FirstThing = {apples, 10} % FirstThing = {apples, 10}
% OtherThingsToBuy = {pears, 6}, {milk, 3} % OtherThingsToBuy = [{pears, 6}, {milk, 3}]
% There are no strings in Erlang. Strings are really just lists of integers. % There are no strings in Erlang. Strings are really just lists of integers.
% Strings are enclosed in double quotation marks (`"`). % Strings are enclosed in double quotation marks (`"`).
@ -117,17 +117,19 @@ c(geometry). % {ok,geometry}
geometry:area({rectangle, 10, 5}). % 50 geometry:area({rectangle, 10, 5}). % 50
geometry:area({circle, 1.4}). % 6.15752 geometry:area({circle, 1.4}). % 6.15752
% In Erlang, two functions with the same name and different arity (number of arguments) % In Erlang, two functions with the same name and different arity (number of
% in the same module represent entirely different functions. % arguments) in the same module represent entirely different functions.
-module(lib_misc). -module(lib_misc).
-export([sum/1]). % export function `sum` of arity 1 accepting one argument: list of integers. -export([sum/1]). % export function `sum` of arity 1
% accepting one argument: list of integers.
sum(L) -> sum(L, 0). sum(L) -> sum(L, 0).
sum([], N) -> N; sum([], N) -> N;
sum([H|T], N) -> sum(T, H+N). sum([H|T], N) -> sum(T, H+N).
% Funs are "anonymous" functions. They are called this way because they have no % Funs are "anonymous" functions. They are called this way because they have
% name. However they can be assigned to variables. % no name. However, they can be assigned to variables.
Double = fun(X) -> 2*X end. % `Double` points to an anonymous function with handle: #Fun<erl_eval.6.17052888> Double = fun(X) -> 2 * X end. % `Double` points to an anonymous function
% with handle: #Fun<erl_eval.6.17052888>
Double(2). % 4 Double(2). % 4
% Functions accept funs as their arguments and can return funs. % Functions accept funs as their arguments and can return funs.
@ -140,8 +142,9 @@ Triple(5). % 15
% The notation `[F(X) || X <- L]` means "the list of `F(X)` where `X` is taken % The notation `[F(X) || X <- L]` means "the list of `F(X)` where `X` is taken
% from the list `L`." % from the list `L`."
L = [1,2,3,4,5]. L = [1,2,3,4,5].
[2*X || X <- L]. % [2,4,6,8,10] [2 * X || X <- L]. % [2,4,6,8,10]
% A list comprehension can have generators and filters which select subset of the generated values. % A list comprehension can have generators and filters, which select subset of
% the generated values.
EvenNumbers = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4] EvenNumbers = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4]
% Guards are constructs that we can use to increase the power of pattern % Guards are constructs that we can use to increase the power of pattern
@ -155,17 +158,31 @@ max(X, Y) -> Y.
% A guard is a series of guard expressions, separated by commas (`,`). % A guard is a series of guard expressions, separated by commas (`,`).
% The guard `GuardExpr1, GuardExpr2, ..., GuardExprN` is true if all the guard % The guard `GuardExpr1, GuardExpr2, ..., GuardExprN` is true if all the guard
% expressions `GuardExpr1, GuardExpr2, ...` evaluate to true. % expressions `GuardExpr1`, `GuardExpr2`, ..., `GuardExprN` evaluate to `true`.
is_cat(A) when is_atom(A), A =:= cat -> true; is_cat(A) when is_atom(A), A =:= cat -> true;
is_cat(A) -> false. is_cat(A) -> false.
is_dog(A) when is_atom(A), A =:= dog -> true; is_dog(A) when is_atom(A), A =:= dog -> true;
is_dog(A) -> false. is_dog(A) -> false.
% A `guard sequence` is either a single guard or a series of guards, separated % We won't dwell on the `=:=` operator here; just be aware that it is used to
%by semicolons (`;`). The guard sequence `G1; G2; ...; Gn` is true if at least % check whether two Erlang expressions have the same value *and* the same type.
% one of the guards `G1, G2, ...` evaluates to true. % Contrast this behaviour to that of the `==` operator:
is_pet(A) when is_dog(A); is_cat(A) -> true; 1 + 2 =:= 3. % true
is_pet(A) -> false. 1 + 2 =:= 3.0. % false
1 + 2 == 3.0. % true
% A guard sequence is either a single guard or a series of guards, separated
% by semicolons (`;`). The guard sequence `G1; G2; ...; Gn` is true if at
% least one of the guards `G1`, `G2`, ..., `Gn` evaluates to `true`.
is_pet(A) when is_atom(A), (A =:= dog) or (A =:= cat) -> true;
is_pet(A) -> false.
% Warning: not all valid Erlang expressions can be used as guard expressions;
% in particular, our `is_cat` and `is_dog` functions cannot be used within the
% guard sequence in `is_pet`'s definition. For a description of the
% expressions allowed in guard sequences, refer to this
% [section](http://erlang.org/doc/reference_manual/expressions.html#id81912)
% of the Erlang reference manual.
% Records provide a method for associating a name with a particular element in a % Records provide a method for associating a name with a particular element in a
% tuple. % tuple.
@ -188,7 +205,7 @@ X = #todo{}.
X1 = #todo{status = urgent, text = "Fix errata in book"}. X1 = #todo{status = urgent, text = "Fix errata in book"}.
% #todo{status = urgent, who = joe, text = "Fix errata in book"} % #todo{status = urgent, who = joe, text = "Fix errata in book"}
X2 = X1#todo{status = done}. X2 = X1#todo{status = done}.
% #todo{status = done,who = joe,text = "Fix errata in book"} % #todo{status = done, who = joe, text = "Fix errata in book"}
% `case` expressions. % `case` expressions.
% `filter` returns a list of all elements `X` in a list `L` for which `P(X)` is % `filter` returns a list of all elements `X` in a list `L` for which `P(X)` is
@ -209,8 +226,8 @@ max(X, Y) ->
true -> nil true -> nil
end. end.
% Warning: at least one of the guards in the `if` expression must evaluate to true; % Warning: at least one of the guards in the `if` expression must evaluate to
% otherwise, an exception will be raised. % `true`; otherwise, an exception will be raised.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -218,7 +235,7 @@ max(X, Y) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Exceptions are raised by the system when internal errors are encountered or % Exceptions are raised by the system when internal errors are encountered or
% explicitly in code by calling `throw(Exception)`, `exit(Exception)` or % explicitly in code by calling `throw(Exception)`, `exit(Exception)`, or
% `erlang:error(Exception)`. % `erlang:error(Exception)`.
generate_exception(1) -> a; generate_exception(1) -> a;
generate_exception(2) -> throw(a); generate_exception(2) -> throw(a);
@ -227,7 +244,7 @@ generate_exception(4) -> {'EXIT', a};
generate_exception(5) -> erlang:error(a). generate_exception(5) -> erlang:error(a).
% Erlang has two methods of catching an exception. One is to enclose the call to % Erlang has two methods of catching an exception. One is to enclose the call to
% the function, which raised the exception within a `try...catch` expression. % the function that raises the exception within a `try...catch` expression.
catcher(N) -> catcher(N) ->
try generate_exception(N) of try generate_exception(N) of
Val -> {N, normal, Val} Val -> {N, normal, Val}
@ -241,23 +258,24 @@ catcher(N) ->
% exception, it is converted into a tuple that describes the error. % exception, it is converted into a tuple that describes the error.
catcher(N) -> catch generate_exception(N). catcher(N) -> catch generate_exception(N).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 4. Concurrency %% 4. Concurrency
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Erlang relies on the actor model for concurrency. All we need to write % Erlang relies on the actor model for concurrency. All we need to write
% concurrent programs in erlang are three primitives: spawning processes, % concurrent programs in Erlang are three primitives: spawning processes,
% sending messages and receiving messages. % sending messages and receiving messages.
% To start a new process we use the `spawn` function, which takes a function % To start a new process, we use the `spawn` function, which takes a function
% as argument. % as argument.
F = fun() -> 2 + 2 end. % #Fun<erl_eval.20.67289768> F = fun() -> 2 + 2 end. % #Fun<erl_eval.20.67289768>
spawn(F). % <0.44.0> spawn(F). % <0.44.0>
% `spawn` returns a pid (process identifier), you can use this pid to send % `spawn` returns a pid (process identifier); you can use this pid to send
% messages to the process. To do message passing we use the `!` operator. % messages to the process. To do message passing, we use the `!` operator.
% For all of this to be useful we need to be able to receive messages. This is % For all of this to be useful, we need to be able to receive messages. This is
% achieved with the `receive` mechanism: % achieved with the `receive` mechanism:
-module(calculateGeometry). -module(calculateGeometry).
@ -272,12 +290,13 @@ calculateArea() ->
io:format("We can only calculate area of rectangles or circles.") io:format("We can only calculate area of rectangles or circles.")
end. end.
% Compile the module and create a process that evaluates `calculateArea` in the shell % Compile the module and create a process that evaluates `calculateArea` in the
% shell.
c(calculateGeometry). c(calculateGeometry).
CalculateArea = spawn(calculateGeometry, calculateArea, []). CalculateArea = spawn(calculateGeometry, calculateArea, []).
CalculateArea ! {circle, 2}. % 12.56000000000000049738 CalculateArea ! {circle, 2}. % 12.56000000000000049738
% The shell is also a process, you can use `self` to get the current pid % The shell is also a process; you can use `self` to get the current pid.
self(). % <0.41.0> self(). % <0.41.0>
``` ```

View File

@ -0,0 +1,327 @@
---
language: erlang
contributors:
- ["Giovanni Cappellotto", "http://www.focustheweb.com/"]
translators:
- ["Julien Cretel", "https://github.com/Jubobs"]
filename: learnerlang-fr.erl
lang: fr-fr
---
```erlang
% Un signe pour cent marque le début d'un commentaire de fin de ligne.
%% Deux signes pour cent sont utilisés pour commenter les fonctions.
%%% Trois signes pour cent sont utilisés pour commenter les modules.
% Trois symboles de ponctuation sont utilisés en Erlang.
% Les virgules (`,`) servent à séparer les paramètres dans les appels de
% fonctions, les contructeurs, et les motifs.
% Les points (`.`) (suivis par des blancs) servent à séparer les fonctions et
% les expressions dans l'interpréteur.
% Les points-virgules (`;`) servent à séparer les clauses. Ces dernières
% apparaissent dans différent cas de figure : définitions de fonctions et
% expressions `case`, `if`, `try..catch`, `receive`.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 1. Variables et filtrage par motif
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
(L'équivalent anglais de *filtrage par motif* est *pattern patching*.)
Nb = 42. % Chaque nom de variable doit commencer par une lettre majuscule.
% Les variables Erlang ne peuvent être affectées qu'une seule fois ; si vous
% essayez d'affecter une autre valeur à la variable `Nb`, vous obtiendrez
% une erreur.
Nb = 43. % ** exception error: no match of right hand side value 43
% Dans la plupart des languages, `=` indique une affectation. En Erlang,
% cependant, `=` indique un filtrage par motif. En fait, `Gauche = Droit`
% signifie ce qui suit : évalue le côté droit (`Droit`), et ensuite filtre le
% résultat à l'aide du motif du côté gauche (`Gauche`).
Nb = 7 * 6.
% Nombre en virgule flottante.
Pi = 3.14159.
% Les atomes représentent des valeurs constantes non-numériques. Un atome
% commence par une lettre minuscule, suivie d'une séquence composée de
% caractères alphanumériques, de tirets bas (`_`), ou d'arobases (`@`).
Bonjour = bonjour.
AutreNoeud = exemple@noeud.
% Les atomes de valeur autre qu'alphanumérique peuvent être délimités par
% des guillemets droits simples.
AtomeAvecEspace = 'un atome contenant des espaces'.
% Les tuples sont similaires aux enregistrements du language C.
Point = {point, 10, 45}.
% Pour extraire des valeurs d'un tuple, on filtre par motif avec
% l'opérateur `=`.
{point, X, Y} = Point. % X = 10, Y = 45
% On peut utiliser `_` comme caractère joker pour les variables qui ne nous
% intéressent pas. Le symbol `_` est appelé variable muette. Contrairement
% aux variables normales, de multiples apparitions de `_` dans un même motif
% ne lient pas nécessairement à la même valeur.
Personne = {personne, {nom, {prenom, joe}, {famille, armstrong}},
{pointure, 42}}.
{_, {_, {_, Qui}, _}, _} = Personne. % Qui = joe
% Pour créer une liste, on écrit les éléments de la liste entre crochets, en
% les séparant par des virgules.
% Les éléments d'une liste peuvent avoir n'importe quel type.
% Le premier élément d'une liste est appelé la tête de la liste. Si on retire
% la tête d'une liste, ce qui reste est appelée la queue de la liste.
Articles = [{pommes, 10}, {poires, 6}, {lait, 3}].
% Si `Q` est une liste, alors `[T|Q]` est aussi une liste dont la tête est `T`
% et dont la queue est `Q`. La barre verticale (`|`) sépare la tête d'une
% liste de sa queue.
% `[]` est la liste vide.
% On peut extraire des éléments d'une liste par filtrage de motif. Si `L` est
% une liste non vide, alors l'expression `[X|Y] = L`, où `X` et `Y` sont des
% variables non affectées, va extraire la tête de la liste dans `X` et la
% queue de la liste dans `Y`.
[PremierArticle|AutresArticles] = Articles.
% PremierArticle = {pommmes, 10}
% AutresArticles = [{poires, 6}, {lait, 3}]
% Il n'y a pas de chaînes de caractères en Erlang. Les chaînes de caractères
% ne sont rien de plus que des listes d'entiers.
% Les chaînes de caractères sont délimitées par des guillemets droits doubles
% (`"`).
Nom = "Bonjour".
[66, 111, 110, 106, 111, 117, 114] = "Bonjour".
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 2. Programmation séquentielle.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Les modules constituent l'unité de base d'un programme Erlang. Toutes les
% fonctions que l'on écrit sont enregistrées dans des modules. Les modules sont
% enregistrés dans des fichiers avec une extension `.erl`.
% Les modules doivent être compilés afin d'éxecuter le programme.
% Un module compilé a une extension `.beam`.
-module(geometrie).
-export([aire/1]). % la liste des fonctions exportées par le module.
% La fonction `aire` est composée de deux clauses. Les clauses sont séparées
% par un point-virgule, et la dernière clause est suivie d'un point et un
% espace blanc. Chaque clause a une en-tête et un corps ; l'en-tête consiste
% en un nom de fonction suivi d'un motif (entre parenthèses), et le corps
% consiste en une séquence d'expressions, qui sont évaluées si le motif de
% l'en-tête est cohérent par rapport à la valeur des paramètres d'appel.
% L'expression est filtrée séquentiellement par les différents motifs, dans
% l'ordre dans lequel ils apparaissent dans la définition de la fonction.
aire({rectangle, Largeur, Hauteur}) -> Largeur * Hauteur;
aire({cercle, R}) -> 3.14159 * R * R.
% Compilation du code du fichier geometrie.erl.
c(geometrie). % {ok,geometrie}
% Le nom du module doit être inclus avec le nom de la fonction afin
% d'identifier précisément quelle fonction on souhaite appeler.
geometrie:aire({rectangle, 10, 5}). % 50
geometrie:area({cercle, 1.4}). % 6.15752
% En Erlang, deux fonctions portant le même nom mais ayant des arités
% différentes (c'est à dire ne prenant pas le même nombre de paramètres)
% au sein d'un même module représentent des fonctions complètement
% différentes.
-module(lib_divers).
-export([somme/1]). % exporte la fonction `somme` d'arité 1
% acceptant un paramètre : une liste d'entiers.
somme(L) -> somme(L, 0).
somme([], N) -> N;
somme([T|Q], N) -> somme(Q, T+N).
% Les `fun`s sont des fonctions "anonymes" ; elles sont appelées ainsi parce
% qu'elles n'ont pas de nom. Cependant, elles peuvent être affectées à des
% variables.
Doubler = fun(X) -> 2 * X end. % `Doubler` pointe vers une fonction anonyme
% dont le handle est : #Fun<erl_eval.6.17052888>
Doubler(2). % 4
% Les fonctions peuvent prendre des `fun`s comme paramètres et peuvent renvoyer
% des `fun`s.
Mult = fun(Fois) -> ( fun(X) -> X * Fois end ) end.
Tripler = Mult(3).
Tripler(5). % 15
% Les listes en compréhension sont des expressions qui créent des listes sans
% requérir ni `fun`s, ni maps, ni filters.
% La notation `[F(X) || X <- L]` signifie "la liste des `F(X)``X` est
% extrait de la liste `L`."
L = [1,2,3,4,5].
[2 * X || X <- L]. % [2,4,6,8,10]
% Une liste en compréhension peut être constituée de générateurs, ainsi que de
% gardes, qui sélectionnent un sous-ensemble des valeurs générées.
NombresPairs = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4]
% La garde est un élément syntaxique qui rend le filtrage par motif encore
% plus puissant. Les gardes permettent de d'effectuer de simple tests et
% comparaisons sur les variables d'un motif. Les gardes peuvent être
% utilisées dans les en-têtes de fonctions, au sein desquelles elles sont
% introduites par le mot-clé `when`, ou encore à n'importe quel endroit où
% une expression est autorisée.
max(X, Y) when X > Y -> X;
max(X, Y) -> Y.
% Une garde est une série d'expressions gardes, séparées par des virgules (`,`).
% La garde `ExprGarde1, ExprGarde2, ..., ExprGardeN` est vraie si toutes les
% expressions gardes `ExprGarde1`, `ExprGarde2, ..., `ExprGardeN` ont pour
% valeur `true`.
est_chat(A) when is_atom(A), A =:= chat -> true;
est_chat(A) -> false.
est_chien(A) when is_atom(A), A =:= chien -> true;
est_chien(A) -> false.
% Une séquence de gardes est composée soit d'une seule garde ou bien d'une
% série de gardes, séparées par des points-virgules (`;`). La séquence de
% gardes `G1; G2; ...; Gn` est vraie si au moins l'une des gardes `G1`, `G2`,
% ..., `Gn` a pour valeur `true`.
est_animal(A) when is_atom(A), (A =:= chien) or (A =:= chat) -> true;
est_animal(A) -> false.
% Attention : toutes les expressions Erlang valides ne peuvent pas être
% utilisées comme expressions gardes ; en particulier, nos fonctions
% `est_chat` et `est_chien` ne sont pas autorisées au sein de la séquence de
% gardes dans la définition de `est_animal`. Pour plus de détails sur les
% expressions autorisées ands les séquences de gardes, voir cette
% [section](http://erlang.org/doc/reference_manual/expressions.html#id81912)
% du manuel Erlang.
% Les enregistrements permettent d'associer un nom à un certain élément dans
% un tuple.
% Les enregistrements peuvent être définis dans des fichiers sources Erlang
% ou bien dans des fichiers avec une extension `.hrl`, qui sont ensuite inclus
% dans des fichiers sources Erlang.
-record(afaire, {
statut = rappel, % Valeur par défaut
qui = joe,
texte
}).
% Les définitions d'enregistrements doivent être lues dans l'interpreteur
% pour qu'on puisse définir un enregistrement. On utilise la fonction `rr`
% (abbréviation de *read records* en anglais, ou *lire enregistrements* en
% français) pour ça.
rr("enregistrements.hrl"). % [afaire]
% Création et mise à jour d'enregistrements :
X = #afaire{}.
% #afaire{statut = rappel, qui = joe, texte = undefined}
X1 = #afaire{statut = urgent, texte = "Corriger erreurs dans livre"}.
% #afaire{statut = urgent, qui = joe, texte = "Corriger erreurs dans livre"}
X2 = X1#afaire{statut = fini}.
% #afaire{statut = fini, qui = joe, texte = "Corriger erreurs dans livre"}
% Expressions `case`.
% `filter` renvoie une liste de tous les éléments `X` d'une liste `L` pour
% lesquels `P(X)` est vrai.
filter(P, [H|T]) ->
case P(H) of
true -> [H|filter(P, T)];
false -> filter(P, T)
end;
filter(P, []) -> [].
filter(fun(X) -> X rem 2 == 0 end, [1, 2, 3, 4]). % [2, 4]
% Expressions `if`.
max(X, Y) ->
if
X > Y -> X;
X < Y -> Y;
true -> nil
end.
% Attention : au moins l'une des gardes dans l'expression `if` doit avoir pour
% valeur `true` ; autrement, une exception sera lancée.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 3. Exceptions.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Des exceptions sont lancées par le système quand des erreurs internes
% surviennent, ou de manière explicite dans le programme en appelant
% `throw(Exception)`, `exit(Exception)`, ou `erlang:error(Exception)`.
generer_exception(1) -> a;
generer_exception(2) -> throw(a);
generer_exception(3) -> exit(a);
generer_exception(4) -> {'EXIT', a};
generer_exception(5) -> erlang:error(a).
% Erlang dispose de deux méthodes pour capturer une exception. La première
% consiste à inclure l'appel de de la fonction qui lance l'exception dans une
% expression `try...catch`.
catcher(N) ->
try generer_exception(N) of
Val -> {N, normal, Val}
catch
throw:X -> {N, caught, thrown, X};
exit:X -> {N, caught, exited, X};
error:X -> {N, caught, error, X}
end.
% L'autre méthode consiste à inclure l'appel dans une expression `catch`.
% Quand une exception est capturée, elle est convertie en un tuple qui décrit
% l'erreur.
catcher(N) -> catch generer_exception(N).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 4. Concurrence
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Erlang est basé sur le modèle d'acteur pour la concurrence. Seulement trois
% opérations sont requises pour écrire des programmes concurrents en Erlang :
% la création de processus, l'envoi de messages, et la réception de messages.
% Pour démarrer un nouveau processus, on utilise la fonction `spawn`, qui
% prend une fonction comme paramètre.
F = fun() -> 2 + 2 end. % #Fun<erl_eval.20.67289768>
spawn(F). % <0.44.0>
% `spawn` renvoie un pid (*process identifier* en anglais, ou *identifiant de
% processus* en français), qui peut être utilisé pour envoyer des messages au
% processus en question. Pour passer des messages, on utilise l'opérateur `!`.
% Pour que cela soit utile, on doit aussi être en mesure de recevoir des
% messages, ce qui est accompli grâce à une clause `receive` :
-module(calculerGeometrie).
-compile(export_all).
calculerAire() ->
receive
{rectangle, W, H} ->
W * H;
{cercle, R} ->
3.14 * R * R;
_ ->
io:format("Seule l'aire d'un rectangle / cercle peut etre calculee.")
end.
% Compilation du module and création d'un processus qui évalue `calculerAire`
% dans l'interpréteur.
c(calculerGeometrie).
CalculerAire = spawn(calculerGeometrie, calculerAire, []).
CalculerAire ! {cercle, 2}. % 12.56000000000000049738
% L'interpréteur est lui-même un processus ; on peut utiliser `self` pour
% obtenir le pid actuel.
self(). % <0.41.0>
```
## Ressources (en anglais)
* ["Learn You Some Erlang for great good!"](http://learnyousomeerlang.com/)
* ["Programming Erlang: Software for a Concurrent World" by Joe Armstrong](http://pragprog.com/book/jaerlang/programming-erlang)
* [Erlang/OTP Reference Documentation](http://www.erlang.org/doc/)
* [Erlang - Programming Rules and Conventions](http://www.erlang.se/doc/programming_rules.shtml)

View File

@ -0,0 +1,62 @@
---
language: json
filename: learnjson-fr.json
contributors:
- ["Anna Harren", "https://github.com/iirelu"]
- ["Marco Scannadinari", "https://github.com/marcoms"]
translators:
- ["Alois de Gouvello","https://github.com/aloisdg"]
lang: fr-fr
---
Comme JSON est un format d'échange de données extrêmement simple, ce Apprendre X en Y minutes
est susceptible d'être le plus simple jamais réalisé.
JSON dans son état le plus pur n'a aucun commentaire, mais la majorité des parseurs accepterons
les commentaires du langage C (`//`, `/* */`). Pour les besoins de ce document, cependant,
tout sera du JSON 100% valide. Heureusement, il s'explique par lui-même.
```json
{
"Clé": "valeur",
"Clés": "devront toujours être entourées par des guillemets",
"nombres": 0,
"chaînes de caractères": "Hellø, wørld. Tous les caractères Unicode sont autorisés, accompagné d'un \"caractère d'échappement\".",
"a des booléens ?": true,
"rien": null,
"grand nombre": 1.2e+100,
"objets": {
"commentaire": "La majorité de votre strucutre sera des objets.",
"tableau": [0, 1, 2, 3, "Les tableaux peuvent contenir n'importe quoi.", 5],
"un autre objet": {
"commentaire": "Ces choses peuvent être imbriquées. C'est très utile."
}
},
"bêtises": [
{
"sources de potassium": ["bananes"]
},
[
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, "neo"],
[0, 0, 0, 1]
]
],
"style alternatif": {
"commentaire": "regarde ça !"
, "position de la virgule": "n'a pas d'importance - aussi longtemps qu'elle est avant la valeur, alors elle est valide."
, "un autre commentaire": "comme c'est gentil"
},
"C'était court": "Et, vous avez terminé. Maintenant, vous savez tout ce que JSON a à offrir."
}
```

747
fr-fr/r-fr.html.markdown Normal file
View File

@ -0,0 +1,747 @@
---
language: R
contributors:
- ["e99n09", "http://github.com/e99n09"]
- ["isomorphismes", "http://twitter.com/isomorphisms"]
translators:
- ["Anne-Catherine Dehier", "https://github.com/spellart"]
filename: learnr-fr.r
lang: fr-fr
---
R est un langage de programmation statistique. Il dispose de nombreuses
bibliothèques pour le téléchargement et le nettoyage d'ensembles de données,
l'exécution de procédures statistiques, et la réalisation de graphiques.
On peut également exécuter des commmandes `R` au sein d'un document LaTeX.
```r
# Les commentaires commencent avec des symboles numériques.
# Il n'est pas possible de faire des commentaires multilignes,
# mais on peut placer plusieurs commentaires les uns en dessous
# des autres comme ceci.
# Sur Mac, taper COMMAND-ENTER pour exécuter une ligne
# et sur Windows taper CTRL-ENTER
########################################################################
# Les choses que vous pouvez faire sans rien comprendre
# à la programmation
########################################################################
# Dans cette section, nous vous montrons quelques trucs cools que vous
# pouvez faire avec R sans rien comprendre à la programmation.
# Ne vous inquiétez pas si vous ne comprenez pas tout ce que le code fait.
# Profitez simplement !
data() # parcours les ensembles de données préchargées
data(rivers) # récupère ceci : "Lengths of Major North American Rivers"
ls() # notez que "rivers" apparaît maintenant dans votre espace de travail
head(rivers) # donne un aperçu des données
# 735 320 325 392 524 450
length(rivers) # Combien de rivers ont été mesurées ?
# 141
summary(rivers) # Quelles sont les principales données statistiques ?
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# 135.0 310.0 425.0 591.2 680.0 3710.0
# Fait un diagramme à tiges et à feuilles (visualisation de données de
# types histogramme)
stem(rivers)
# Le point décimal est de 2 chiffres à droite du |
#
# 0 | 4
# 2 | 011223334555566667778888899900001111223333344455555666688888999
# 4 | 111222333445566779001233344567
# 6 | 000112233578012234468
# 8 | 045790018
# 10 | 04507
# 12 | 1471
# 14 | 56
# 16 | 7
# 18 | 9
# 20 |
# 22 | 25
# 24 | 3
# 26 |
# 28 |
# 30 |
# 32 |
# 34 |
# 36 | 1
stem(log(rivers)) # Notez que les données ne sont ni normales
# ni lognormales !
# Prenez-ça, la courbe en cloche
# Le point décimal est à 1 chiffre à gauche du |
#
# 48 | 1
# 50 |
# 52 | 15578
# 54 | 44571222466689
# 56 | 023334677000124455789
# 58 | 00122366666999933445777
# 60 | 122445567800133459
# 62 | 112666799035
# 64 | 00011334581257889
# 66 | 003683579
# 68 | 0019156
# 70 | 079357
# 72 | 89
# 74 | 84
# 76 | 56
# 78 | 4
# 80 |
# 82 | 2
# Fait un histogramme :
hist(rivers, col="#333333", border="white", breaks=25) # amusez-vous avec ces paramètres
hist(log(rivers), col="#333333", border="white", breaks=25) # vous ferez plus de tracés plus tard
# Ici d'autres données qui viennent préchargées. R en a des tonnes.
data(discoveries)
plot(discoveries, col="#333333", lwd=3, xlab="Year",
main="Number of important discoveries per year")
plot(discoveries, col="#333333", lwd=3, type = "h", xlab="Year",
main="Number of important discoveries per year")
# Plutôt que de laisser l'ordre par défaut (par année)
# Nous pourrions aussi trier pour voir ce qu'il y a de typique
sort(discoveries)
# [1] 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2
# [26] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3
# [51] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4
# [76] 4 4 4 4 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 8 9 10 12
stem(discoveries, scale=2)
#
# Le point décimale est à la |
#
# 0 | 000000000
# 1 | 000000000000
# 2 | 00000000000000000000000000
# 3 | 00000000000000000000
# 4 | 000000000000
# 5 | 0000000
# 6 | 000000
# 7 | 0000
# 8 | 0
# 9 | 0
# 10 | 0
# 11 |
# 12 | 0
max(discoveries)
# 12
summary(discoveries)
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# 0.0 2.0 3.0 3.1 4.0 12.0
# Lance un dé plusieurs fois
round(runif(7, min=.5, max=6.5))
# 1 4 6 1 4 6 4
# Vos numéros diffèreront des miens à moins que nous mettions
# le même random.seed(31337)
# Dessine à partir d'une normale Gaussienne 9 fois
rnorm(9)
# [1] 0.07528471 1.03499859 1.34809556 -0.82356087 0.61638975 -1.88757271
# [7] -0.59975593 0.57629164 1.08455362
##############################################################
# les types de données et l'arithmétique de base
##############################################################
# Maintenant pour la partie orientée programmation du tutoriel.
# Dans cette section vous rencontrerez les types de données importants de R :
# les entiers, les numériques, les caractères, les logiques, et les facteurs.
# LES ENTIERS
# Les entiers de type long sont écrits avec L
5L # 5
class(5L) # "integer"
# (Essayez ?class pour plus d'informations sur la fonction class().)
# Avec R, chaque valeur seule, comme 5L, est considérée comme
# un vecteur de longueur 1
length(5L) # 1
# On peut avoir un vecteur d'entiers avec une longueur > 1 :
c(4L, 5L, 8L, 3L) # 4 5 8 3
length(c(4L, 5L, 8L, 3L)) # 4
class(c(4L, 5L, 8L, 3L)) # "integer"
# LES NUMÉRIQUES
# Un "numeric" est un nombre à virgule flottante d'une précision double
5 # 5
class(5) # "numeric"
# Encore une fois, tout dans R est un vecteur ;
# Vous pouvez faire un vecteur numérique avec plus d'un élément
c(3,3,3,2,2,1) # 3 3 3 2 2 1
# Vous pouvez aussi utiliser la notation scientifique
5e4 # 50000
6.02e23 # nombre d'Avogadro
1.6e-35 # longueur de Planck
# Vous pouvez également avoir des nombres infiniments grands ou petits
class(Inf) # "numeric"
class(-Inf) # "numeric"
# Vous pouvez utiliser "Inf", par exemple, dans integrate(dnorm, 3, Inf);
# Ça permet d'éviter de réaliser une table de la loi normale.
# ARITHMÉTIQUES DE BASE
# Vous pouvez faire de l'arithmétique avec des nombres
# Faire des opérations arithmétiques en mixant des entiers
# et des numériques
# donne un autre numérique
10L + 66L # 76 # un entier plus un entier donne un entier
53.2 - 4 # 49.2 # un numérique moins un numérique donne un numérique
2.0 * 2L # 4 # un numérique multiplié par un entier donne un numérique
3L / 4 # 0.75 # un entier sur un numérique donne un numérique
3 %% 2 # 1 # le reste de deux numériques est un autre numérique
# Les opérations arithmétiques illégales donnent un "Not A Number" :
0 / 0 # NaN
class(NaN) # "numeric"
# Vous pouvez faire des opérations arithmétiques avec deux vecteurs d'une
# longueur plus grande que 1, à condition que la longueur du plus grand
# vecteur soit un multiple entier du plus petit
c(1,2,3) + c(1,2,3) # 2 4 6
# LES CARACTÈRES
# Il n'y a pas de différences entre les chaînes de caractères et
# les caractères en R
"Horatio" # "Horatio"
class("Horatio") # "character"
class('H') # "character"
# Ceux-ci sont tous les deux des vecteurs de longueur 1
# Ici un plus long :
c('alef', 'bet', 'gimmel', 'dalet', 'he')
# =>
# "alef" "bet" "gimmel" "dalet" "he"
length(c("Call","me","Ishmael")) # 3
# Vous pouvez utiliser des expressions rationnelles sur les vecteurs de caractères :
substr("Fortuna multis dat nimis, nulli satis.", 9, 15) # "multis "
gsub('u', 'ø', "Fortuna multis dat nimis, nulli satis.") # "Fortøna møltis dat nimis, nølli satis."
# R possède plusieurs vecteurs de caractères préconstruits :
letters
# =>
# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
# [20] "t" "u" "v" "w" "x" "y" "z"
month.abb # "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
# LES TYPES BOOLÉENS
# En R, un "logical" est un booléen
class(TRUE) # "logical"
class(FALSE) # "logical"
# Leur comportement est normal
TRUE == TRUE # TRUE
TRUE == FALSE # FALSE
FALSE != FALSE # FALSE
FALSE != TRUE # TRUE
# Les données manquantes (NA) sont logiques également
class(NA) # "logical"
# On utilise | et & pour les operations logiques.
# OR
TRUE | FALSE # TRUE
# AND
TRUE & FALSE # FALSE
# Vous pouvez tester si x est TRUE
isTRUE(TRUE) # TRUE
# Ici nous avons un vecteur de type logique avec plusieurs éléments :
c('Z', 'o', 'r', 'r', 'o') == "Zorro" # FALSE FALSE FALSE FALSE FALSE
c('Z', 'o', 'r', 'r', 'o') == "Z" # TRUE FALSE FALSE FALSE FALSE
# LES FACTEURS
# Les facteurs sont généralement utilisés pour y stocker des
# variables qualitatives (catégorielles).
# Les facteurs peuvent être ordonnés (comme le niveau scolaire
# des enfants) ou non ordonnés (comme le sexe)
factor(c("female", "female", "male", NA, "female"))
# female female male <NA> female
# Les niveaux : female male
# Les facteurs possèdent un attribut appelé niveau ("level").
# Les niveaux sont des vecteurs contenant toutes les valeurs
# que peuvent prendre les données catégorielles.
# Notez que les données manquantes n'entrent pas dans le niveau
levels(factor(c("male", "male", "female", NA, "female"))) # "female" "male"
# Si le vecteur de facteurs a une longueur 1, ses niveaux seront
# de longueur 1 également
length(factor("male")) # 1
length(levels(factor("male"))) # 1
# On rencontre communément des facteurs dans des "data frame",
# un type de données que nous couvrirons plus tard
data(infert) # "Infertility after Spontaneous and Induced Abortion"
levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs"
# NULL
# "NULL" est bizarre ; on l'utilise pour effacer un vecteur
class(NULL) # NULL
parakeet = c("beak", "feathers", "wings", "eyes")
parakeet
# =>
# [1] "beak" "feathers" "wings" "eyes"
parakeet <- NULL
parakeet
# =>
# NULL
# LES CONVERSIONS DE TYPES
# Les conversions de types servent à forcer une valeur à prendre
# un type différent
as.character(c(6, 8)) # "6" "8"
as.logical(c(1,0,1,1)) # TRUE FALSE TRUE TRUE
# Si vous mettez des éléments de différents types dans un vecteur,
# des coercitions bizarres se produisent :
c(TRUE, 4) # 1 4
c("dog", TRUE, 4) # "dog" "TRUE" "4"
as.numeric("Bilbo")
# =>
# [1] NA
# Message d'avertissement :
# NAs est introduit par coercition
# Notez également : ce n'étaient que des types de données basiques
# Il y a beaucoup d'autres types de données, comme les dates,
# les séries temporelles, etc ...
#######################################
# Variables, boucles , if/else
#######################################
# Une variable est comme une boîte dans laquelle on garde une valeur
# pour l'utiliser plus tard.
# Nous appellons ça "assigner" une valeur à une variable.
# Avoir des variables nous permet d'écrire des boucles, des fonctions, et
# des instructions conditionnelles (if/else)
# LES VARIABLES
# Beaucoup de façons d'assigner des choses :
x = 5 # c'est correct
y <- "1" # c'est préféré
TRUE -> z # ça marche mais c'est bizarre
# LES BOUCLES
# Il y a les boucles for :
for (i in 1:4) {
print(i)
}
# Il y a les boucles while :
a <- 10
while (a > 4) {
cat(a, "...", sep = "")
a <- a - 1
}
# Gardez à l'esprit que les boucles for et while s'exécutent lentement
# en R.
# Des opérations sur la totalité d'un vecteur (ex une ligne entière,
# une colonne entière),
# ou les fonctions de type apply() (nous en parlerons plus tard),
# sont préférées.
# IF/ELSE
# Encore une fois assez standard
if (4 > 3) {
print("4 is greater than 3")
} else {
print("4 is not greater than 3")
}
# =>
# [1] "4 is greater than 3"
# LES FONCTIONS
# se définissent comme ceci :
jiggle <- function(x) {
x = x + rnorm(1, sd=.1) # ajoute un peu de bruit (contrôlé)
return(x)
}
# Appelées comme n'importe quelles autres fonction R :
jiggle(5) # 5±ε. After set.seed(2716057), jiggle(5)==5.005043
##########################################################################
# Les structures de données : les vecteurs, les matrices,
# les data frames et les tableaux
##########################################################################
# À UNE DIMENSION
# Commençons par le tout début, et avec quelque chose que
# vous connaissez déjà : les vecteurs.
vec <- c(8, 9, 10, 11)
vec # 8 9 10 11
# Nous demandons des éléments spécifiques en les mettant entre crochets
# (Notez que R commence à compter à partir de 1)
vec[1] # 8
letters[18] # "r"
LETTERS[13] # "M"
month.name[9] # "September"
c(6, 8, 7, 5, 3, 0, 9)[3] # 7
# Nous pouvons également rechercher des indices de composants spécifiques,
which(vec %% 2 == 0) # 1 3
# Récupèrer seulement les premières ou dernières entrées du vecteur,
head(vec, 1) # 8
tail(vec, 2) # 10 11
# ou vérifier si un certaine valeur est dans le vecteur
any(vec == 10) # TRUE
# Si un index "dépasse" vous obtiendrez NA :
vec[6] # NA
# Vous pouvez trouver la longueur de votre vecteur avec length()
length(vec) # 4
# Vous pouvez réaliser des opérations sur des vecteurs entiers ou des
# sous-ensembles de vecteurs
vec * 4 # 16 20 24 28
vec[2:3] * 5 # 25 30
any(vec[2:3] == 8) # FALSE
# Et R a beaucoup de méthodes statistiques pré-construites pour les vecteurs :
mean(vec) # 9.5
var(vec) # 1.666667
sd(vec) # 1.290994
max(vec) # 11
min(vec) # 8
sum(vec) # 38
# Quelques fonctions préconstruites sympas supplémentaires :
5:15 # 5 6 7 8 9 10 11 12 13 14 15
seq(from=0, to=31337, by=1337)
# =>
# [1] 0 1337 2674 4011 5348 6685 8022 9359 10696 12033 13370 14707
# [13] 16044 17381 18718 20055 21392 22729 24066 25403 26740 28077 29414 30751
# À DEUX DIMENSIONS (TOUT DANS UNE CLASSE)
# Vous pouvez créer une matrice à partir d'entrées du même type comme ceci :
mat <- matrix(nrow = 3, ncol = 2, c(1,2,3,4,5,6))
mat
# =>
# [,1] [,2]
# [1,] 1 4
# [2,] 2 5
# [3,] 3 6
# Différemment du vecteur, la classe d'une matrice est "matrix",
# peut importe ce qu'elle contient
class(mat) # => "matrix"
# Récupérer la première ligne
mat[1,] # 1 4
# Réaliser une opération sur la première colonne
3 * mat[,1] # 3 6 9
# Demander une cellule spécifique
mat[3,2] # 6
# Transposer la matrice entière
t(mat)
# =>
# [,1] [,2] [,3]
# [1,] 1 2 3
# [2,] 4 5 6
# La multiplication de matrices
mat %*% t(mat)
# =>
# [,1] [,2] [,3]
# [1,] 17 22 27
# [2,] 22 29 36
# [3,] 27 36 45
# cbind() colle des vecteurs ensemble en colonne pour faire une matrice
mat2 <- cbind(1:4, c("dog", "cat", "bird", "dog"))
mat2
# =>
# [,1] [,2]
# [1,] "1" "dog"
# [2,] "2" "cat"
# [3,] "3" "bird"
# [4,] "4" "dog"
class(mat2) # matrix
# Encore une fois regardez ce qui se passe !
# Parce que les matrices peuvent contenir des entrées de toutes sortes de
# classes, tout sera converti en classe caractère
c(class(mat2[,1]), class(mat2[,2]))
# rbind() colle des vecteurs ensemble par lignes pour faire une matrice
mat3 <- rbind(c(1,2,4,5), c(6,7,0,4))
mat3
# =>
# [,1] [,2] [,3] [,4]
# [1,] 1 2 4 5
# [2,] 6 7 0 4
# Ah, tout de la même classe. Pas de coercitions. Beaucoup mieux.
# À DEUX DIMENSIONS (DE CLASSES DIFFÉRENTES)
# Pour des colonnes de différents types, utiliser une data frame
# Cette structure de données est si utile pour la programmation statistique,
# qu'une version a été ajoutée à Python dans le paquet "pandas".
students <- data.frame(c("Cedric","Fred","George","Cho","Draco","Ginny"),
c(3,2,2,1,0,-1),
c("H", "G", "G", "R", "S", "G"))
names(students) <- c("name", "year", "house") # name the columns
class(students) # "data.frame"
students
# =>
# name year house
# 1 Cedric 3 H
# 2 Fred 2 G
# 3 George 2 G
# 4 Cho 1 R
# 5 Draco 0 S
# 6 Ginny -1 G
class(students$year) # "numeric"
class(students[,3]) # "factor"
# Trouver les dimensions
nrow(students) # 6
ncol(students) # 3
dim(students) # 6 3
# La fonction data.frame() convertit les vecteurs caractères en vecteurs de
# facteurs par défaut; désactiver cette fonction en règlant
# stringsAsFactors = FALSE quand vous créer la data.frame
?data.frame
# Il y a plusieurs façons de subdiviser les data frames,
# toutes subtilement différentes
students$year # 3 2 2 1 0 -1
students[,2] # 3 2 2 1 0 -1
students[,"year"] # 3 2 2 1 0 -1
# Une version améliorée de la structure data.frame est data.table.
# Si vous travaillez avec des données volumineuses ou des panels, ou avez
# besoin de fusionner quelques ensembles de données, data.table peut être
# un bon choix. Ici un tour éclair :
install.packages("data.table") # télécharge le paquet depuis CRAN
require(data.table) # le charge
students <- as.data.table(students)
students # regardez la différence à l'impression
# =>
# name year house
# 1: Cedric 3 H
# 2: Fred 2 G
# 3: George 2 G
# 4: Cho 1 R
# 5: Draco 0 S
# 6: Ginny -1 G
students[name=="Ginny"] # obtiens les lignes avec name == "Ginny"
# =>
# name year house
# 1: Ginny -1 G
students[year==2] # obtiens les lignes avec year == 2
# =>
# name year house
# 1: Fred 2 G
# 2: George 2 G
# data.table facilite la fusion entre deux ensembles de données
# Faisons une autre data.table pour fusionner students
founders <- data.table(house=c("G","H","R","S"),
founder=c("Godric","Helga","Rowena","Salazar"))
founders
# =>
# house founder
# 1: G Godric
# 2: H Helga
# 3: R Rowena
# 4: S Salazar
setkey(students, house)
setkey(founders, house)
students <- founders[students] # merge les deux ensembles de données qui matchent "house"
setnames(students, c("house","houseFounderName","studentName","year"))
students[,order(c("name","year","house","houseFounderName")), with=F]
# =>
# studentName year house houseFounderName
# 1: Fred 2 G Godric
# 2: George 2 G Godric
# 3: Ginny -1 G Godric
# 4: Cedric 3 H Helga
# 5: Cho 1 R Rowena
# 6: Draco 0 S Salazar
# data.table facilite le résumé des tableaux
students[,sum(year),by=house]
# =>
# house V1
# 1: G 3
# 2: H 3
# 3: R 1
# 4: S 0
# Pour supprimer une colonne d'une data.frame ou data.table,
# assignez-lui la valeur NULL
students$houseFounderName <- NULL
students
# =>
# studentName year house
# 1: Fred 2 G
# 2: George 2 G
# 3: Ginny -1 G
# 4: Cedric 3 H
# 5: Cho 1 R
# 6: Draco 0 S
# Supprimer une ligne en subdivisant
# En utilisant data.table :
students[studentName != "Draco"]
# =>
# house studentName year
# 1: G Fred 2
# 2: G George 2
# 3: G Ginny -1
# 4: H Cedric 3
# 5: R Cho 1
# En utilisant data.frame :
students <- as.data.frame(students)
students[students$house != "G",]
# =>
# house houseFounderName studentName year
# 4 H Helga Cedric 3
# 5 R Rowena Cho 1
# 6 S Salazar Draco 0
# MULTI-DIMENSIONNELLE (TOUS ÉLÉMENTS D'UN TYPE)
# Les arrays créent des tableaux de n dimensions.
# Tous les éléments doivent être du même type.
# Vous pouvez faire un tableau à 2 dimensions (une sorte de matrice)
array(c(c(1,2,4,5),c(8,9,3,6)), dim=c(2,4))
# =>
# [,1] [,2] [,3] [,4]
# [1,] 1 4 8 3
# [2,] 2 5 9 6
# Vous pouvez aussi utiliser array pour faire des matrices à 3 dimensions :
array(c(c(c(2,300,4),c(8,9,0)),c(c(5,60,0),c(66,7,847))), dim=c(3,2,2))
# =>
# , , 1
#
# [,1] [,2]
# [1,] 2 8
# [2,] 300 9
# [3,] 4 0
#
# , , 2
#
# [,1] [,2]
# [1,] 5 66
# [2,] 60 7
# [3,] 0 847
# LES LISTES (MULTI-DIMENSIONNELLES, ÉVENTUELLEMMENT DÉCHIRÉES,
# DE DIFFÉRENTS TYPES)
# Enfin, R a des listes (de vecteurs)
list1 <- list(time = 1:40)
list1$price = c(rnorm(40,.5*list1$time,4)) # random
list1
# Vous pouvez obtenir des éléments de la liste comme ceci
list1$time # une façon
list1[["time"]] # une autre façon
list1[[1]] # encore une façon différente
# =>
# [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
# [34] 34 35 36 37 38 39 40
# Vous pouvez subdiviser les éléments d'une liste comme n'importe quel vecteur
list1$price[4]
# Les listes ne sont pas les structures de données les plus efficaces
# à utiliser avec R ;
# À moins d'avoir une très bonne raison, vous devriez utiliser data.frames
# Les listes sont souvent retournées par des fonctions qui effectuent
# des régressions linéaires.
##########################################
# La famille de fonction apply()
##########################################
# Vous vous rappelez mat ?
mat
# =>
# [,1] [,2]
# [1,] 1 4
# [2,] 2 5
# [3,] 3 6
# Utilisez apply(X, MARGIN, FUN) pour appliquer la fonction FUN à la matrice X
# sur les lignes (MAR = 1) ou les colonnes (MAR = 2)
# R exécute FUN à chaque lignes (ou colonnes) de X, beaucoup plus rapidement
# que le ferait une boucle for ou while
apply(mat, MAR = 2, jiggle)
# =>
# [,1] [,2]
# [1,] 3 15
# [2,] 7 19
# [3,] 11 23
# D'autres fonctions : ?lapply, ?sapply
# Ne soyez pas trop intimidé ; tout le monde reconnaît que c'est un peu déroutant
# Le paquet plyr vise à remplacer (et améliorer !) la famille *apply().
install.packages("plyr")
require(plyr)
?plyr
############################
# Charger des données
############################
# "pets.csv" est un fichier sur internet
# (mais il pourrait être tout aussi facilement sur votre ordinateur)
pets <- read.csv("http://learnxinyminutes.com/docs/pets.csv")
pets
head(pets, 2) # first two rows
tail(pets, 1) # last row
# Pour sauvegarder une data frame ou une matrice en fichier .csv
write.csv(pets, "pets2.csv") # to make a new .csv file
# définir le répertoire de travail avec setwd(), le récupérer avec getwd()
# Essayez ?read.csv et ?write.csv pour plus d'informations
################
# Les tracés
################
# LES FONCTIONS DE TRACÉ PRÉCONSTRUITES
# Les diagrammes de dispersion !
plot(list1$time, list1$price, main = "fake data")
# Les régressions !
linearModel <- lm(price ~ time, data = list1)
linearModel # sort le résultat de la régression
# Tracer une ligne de regression sur une tracé existant
abline(linearModel, col = "red")
# Obtenir une variété de diagnostiques sympas
plot(linearModel)
# Les histogrammes !
hist(rpois(n = 10000, lambda = 5), col = "thistle")
# Les diagrammes en bâtons !
barplot(c(1,4,5,1,2), names.arg = c("red","blue","purple","green","yellow"))
# GGPLOT2
# Mais ceux-ci ne sont même pas les plus jolis tracés de R
# Essayez le paquet ggplot2 pour d'avantages de graphiques
install.packages("ggplot2")
require(ggplot2)
?ggplot2
pp <- ggplot(students, aes(x=house))
pp + geom_histogram()
ll <- as.data.table(list1)
pp <- ggplot(ll, aes(x=time,price))
pp + geom_point()
# ggplot2 a une documentation excellente
#(disponible sur http://docs.ggplot2.org/current/)
```
## Comment obtenir R ?
* Obtiens R et R GUI depuis [http://www.r-project.org/](http://www.r-project.org/)
* [RStudio](http://www.rstudio.com/ide/) est un autre GUI

View File

@ -0,0 +1,174 @@
---
language: TypeScript
contributors:
- ["Philippe Vlérick", "https://github.com/pvlerick"]
translators:
- ["Alois de Gouvello", "https://github.com/aloisdg"]
filename: learntypescript-fr.ts
lang: fr-fr
---
TypeScript est un langage visant à faciliter le développement d'applications larges et scalables, écrites en JavaScript.
TypeScript ajoute des concepts classiques comme les classes, les modules, les interfaces, les génériques et le typage statique (optionnel) à JavaScript.
C'est une surcouche de JavaScript : tout le code JavaScript est valide en TypeScript ce qui permet de l'ajouter de façon transparente à n'importe quel projet. Le code TypeScript est transcompilé en JavaScript par le compilateur.
Cet article se concentrera seulement sur la syntaxe supplémentaire de TypeScript, plutôt que celle de [JavaScript] (../javascript/).
Pour tester le compilateur de TypeScript, rendez-vous au [Playground] (http://www.typescriptlang.org/Playground) où vous pourrez coder, profiter d'une autocomplétion et accéder directement au rendu JavaScript.
```js
// Il y a 3 types basiques en TypeScript
var isDone: boolean = false;
var lines: number = 42;
var name: string = "Anders";
// Si nous ne pouvons pas déterminer le type, on utilise `Any`
var notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // ok, définitivement un booléen
// Pour les collections, il y a les tableaux typés et les tableaux génériques
var list: number[] = [1, 2, 3]; // Un tableaux typé
var list: Array<number> = [1, 2, 3]; // un tableau générique
// Pour les énumeration
enum Color { Red, Green, Blue };
var c: Color = Color.Green;
// Enfin, `void` est utilisé dans le cas spécifique
// d'une fonction ne retournant rien
function bigHorribleAlert(): void {
alert("Je suis une petite boîte ennuyeuse !");
}
// Les fonctions sont des entités de première classe. Le langage supporte
// les expressions lambda et utilise l'inférence de type
// Les fonctions ci-dessous sont équivalentes, une signature identique
// sera inférée par le compilateur, et le même JavaScript sera généré
var f1 = function(i: number): number { return i * i; }
// Retourne un type inféré
var f2 = function(i: number) { return i * i; }
var f3 = (i: number): number => { return i * i; }
// Retourne un type inféré
var f4 = (i: number) => { return i * i; }
// Retourne un type inféré, ici le mot clé `return` n'est pas nécessaire
var f5 = (i: number) => i * i;
// Les interfaces sont structurées, tout les objets qui ont ces propriétés
// sont compatible avec l'interface
interface Person {
name: string;
// Les propriétés optionnelles sont identifiées avec un "?"
age?: number;
// Et bien sûr, les fonctions
move(): void;
}
// Un objet implémentant l'interface "Person" peut être traité comme
// une Person car il a les propriétés "name" et "move"
var p: Person = { name: "Bobby", move: () => {} };
// Des objets implémentants la propriété optionnelle :
// valide car "age" est un nombre
var validPerson: Person = { name: "Bobby", age: 42, move: () => {} };
// invalide car "age" n'est pas un nombre
var invalidPerson: Person = { name: "Bobby", age: true };
// Les interfaces peuvent aussi décrire un type de fonction
interface SearchFunc {
(source: string, subString: string): boolean;
}
// Seul les types des paramètres sont importants. Les noms ne le sont pas.
var mySearch: SearchFunc;
mySearch = function(src: string, sub: string) {
return src.search(sub) != -1;
}
// Les membres des classes sont publiques par défaut.
class Point {
// Propriétés
x: number;
// Constructeur - Les mots clés "public" et "private" dans ce contexte
// génèrent le code de la propriété et son initialisation dans le
// constructeur. Ici, "y" sera défini de la même façon que "x",
// mais avec moins de code. Les valeurs par défaut sont supportées.
constructor(x: number, public y: number = 0) {
this.x = x;
}
// Fonctions
dist() { return Math.sqrt(this.x * this.x + this.y * this.y); }
// Membres statiques
static origin = new Point(0, 0);
}
var p1 = new Point(10 ,20);
var p2 = new Point(25); // y sera 0
// Héritage
class Point3D extends Point {
constructor(x: number, y: number, public z: number = 0) {
// Un appel explicite au constructeur de la super classe
// est obligatoire.
super(x, y);
}
// Redéfinition
dist() {
var d = super.dist();
return Math.sqrt(d * d + this.z * this.z);
}
}
// Modules, "." peut être utilisé comme un séparateur de sous modules.
module Geometry {
export class Square {
constructor(public sideLength: number = 0) {
}
area() {
return Math.pow(this.sideLength, 2);
}
}
}
var s1 = new Geometry.Square(5);
// Alias local pour référencer un module
import G = Geometry;
var s2 = new G.Square(10);
// Génériques
// Classes
class Tuple<T1, T2> {
constructor(public item1: T1, public item2: T2) {
}
}
// Interfaces
interface Pair<T> {
item1: T;
item2: T;
}
// Et fonctions
var pairToTuple = function<T>(p: Pair<T>) {
return new Tuple(p.item1, p.item2);
};
var tuple = pairToTuple({ item1:"hello", item2:"world"});
// Inclure des références à un fichier :
/// <reference path="jquery.d.ts" />
```
## Lectures complémentaires
* [Site officiel de TypeScript] (http://www.typescriptlang.org/)
* [Spécification du langage TypeScript (pdf)] (http://go.microsoft.com/fwlink/?LinkId=267238)
* [Anders Hejlsberg - Introducing TypeScript on Channel 9] (http://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript)
* [Code source sur GitHub] (https://github.com/Microsoft/TypeScript)
* [Definitely Typed - repository for type definitions] (http://definitelytyped.org/)

View File

@ -79,6 +79,11 @@ this pointer will automatically update and point to the latest commit.
HEAD is a pointer that points to the current branch. A repository only has 1 *active* HEAD. HEAD is a pointer that points to the current branch. A repository only has 1 *active* HEAD.
head is a pointer that points to any commit. A repository can have any number of heads. head is a pointer that points to any commit. A repository can have any number of heads.
###Stages of Git
* Modified - Changes have been made to a file but file has not been committed to Git Database yet
* Staged - Marks a modified file to go into your next commit snapshot
* Committed - Files have been committed to the Git Database
### Conceptual Resources ### Conceptual Resources
* [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/) * [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/)
@ -131,6 +136,10 @@ $ git help -a
$ git help add $ git help add
$ git help commit $ git help commit
$ git help init $ git help init
# or git <command_here> --help
$ git add --help
$ git commit --help
$ git init --help
``` ```
### status ### status
@ -149,8 +158,8 @@ $ git help status
### add ### add
To add files to the current working tree/directory/repo. If you do not `git add` new files to the To add files to the staging area/index. If you do not `git add` new files to the
working tree/directory, they will not be included in commits! staging area/index, they will not be included in commits!
```bash ```bash
# add a file in your current working directory # add a file in your current working directory
@ -163,6 +172,8 @@ $ git add /path/to/file/HelloWorld.c
$ git add ./*.java $ git add ./*.java
``` ```
This only adds a file to the staging area/index, it doesn't commit it to the working directory/repo.
### branch ### branch
Manage your branches. You can view, edit, create, delete branches using this command. Manage your branches. You can view, edit, create, delete branches using this command.
@ -462,3 +473,5 @@ $ git rm /pather/to/the/file/HelloWorld.c
* [GitGuys](http://www.gitguys.com/) * [GitGuys](http://www.gitguys.com/)
* [Git - the simple guide](http://rogerdudler.github.io/git-guide/index.html) * [Git - the simple guide](http://rogerdudler.github.io/git-guide/index.html)
* [Pro Git](http://www.git-scm.com/book/en/v2)

View File

@ -6,7 +6,7 @@ contributors:
filename: learngroovy.groovy filename: learngroovy.groovy
--- ---
Groovy - A dynamic language for the Java platform [Read more here.](http://groovy.codehaus.org) Groovy - A dynamic language for the Java platform [Read more here.](http://www.groovy-lang.org/)
```groovy ```groovy
@ -231,7 +231,7 @@ for ( e in map ) {
Operators Operators
Operator Overloading for a list of the common operators that Groovy supports: Operator Overloading for a list of the common operators that Groovy supports:
http://groovy.codehaus.org/Operator+Overloading http://www.groovy-lang.org/operators.html#Operator-Overloading
Helpful groovy operators Helpful groovy operators
*/ */
@ -249,7 +249,7 @@ def username = user?.username
A Groovy Closure is like a "code block" or a method pointer. It is a piece of A Groovy Closure is like a "code block" or a method pointer. It is a piece of
code that is defined and then executed at a later point. code that is defined and then executed at a later point.
More info at: http://groovy.codehaus.org/Closures+-+Formal+Definition More info at: http://www.groovy-lang.org/closures.html
*/ */
//Example: //Example:
def clos = { println "Hello World!" } def clos = { println "Hello World!" }
@ -405,11 +405,11 @@ assert sum(2,5) == 7
## Further resources ## Further resources
[Groovy documentation](http://groovy.codehaus.org/Documentation) [Groovy documentation](http://www.groovy-lang.org/documentation.html)
[Groovy web console](http://groovyconsole.appspot.com/) [Groovy web console](http://groovyconsole.appspot.com/)
Join a [Groovy user group](http://groovy.codehaus.org/User+Groups) Join a [Groovy user group](http://www.groovy-lang.org/usergroups.html)
## Books ## Books

View File

@ -282,7 +282,7 @@ foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16 foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
-- This is now the same as -- This is now the same as
(2 * 3 + (2 * 2 + (2 * 1 + 4))) (2 * 1 + (2 * 2 + (2 * 3 + 4)))
---------------------------------------------------- ----------------------------------------------------
-- 7. Data Types -- 7. Data Types

View File

@ -323,7 +323,7 @@ class LearnHaxe3{
var l = 0; var l = 0;
do{ do{
trace("do statement always runs at least once"); trace("do statement always runs at least once");
} while (i > 0); } while (l > 0);
// for loop // for loop
/* /*
@ -340,7 +340,7 @@ class LearnHaxe3{
// (more on ranges later as well) // (more on ranges later as well)
var n = ['foo', 'bar', 'baz']; var n = ['foo', 'bar', 'baz'];
for (val in 0...n.length){ for (val in 0...n.length){
trace(val + " is the value for val (an index for m)"); trace(val + " is the value for val (an index for n)");
} }
@ -375,7 +375,7 @@ class LearnHaxe3{
case "rex" : favorite_thing = "shoe"; case "rex" : favorite_thing = "shoe";
case "spot" : favorite_thing = "tennis ball"; case "spot" : favorite_thing = "tennis ball";
default : favorite_thing = "some unknown treat"; default : favorite_thing = "some unknown treat";
// case _ : "some unknown treat"; // same as default // case _ : favorite_thing = "some unknown treat"; // same as default
} }
// The "_" case above is a "wildcard" value // The "_" case above is a "wildcard" value
// that will match anything. // that will match anything.
@ -397,7 +397,7 @@ class LearnHaxe3{
// if statements // if statements
var k = if (true) 10 else 20; var k = if (true) 10 else 20;
trace("K equals ", k); // outputs 10 trace("k equals ", k); // outputs 10
var other_favorite_thing = switch(my_dog_name) { var other_favorite_thing = switch(my_dog_name) {
case "fido" : "teddy"; case "fido" : "teddy";
@ -495,8 +495,10 @@ class LearnHaxe3{
// foo_instance.public_read = 4; // this will throw an error if uncommented: // foo_instance.public_read = 4; // this will throw an error if uncommented:
// trace(foo_instance.public_write); // as will this. // trace(foo_instance.public_write); // as will this.
trace(foo_instance + " is the value for foo_instance"); // calls the toString method // calls the toString method:
trace(foo_instance.toString() + " is the value for foo_instance.toString()"); // same thing trace(foo_instance + " is the value for foo_instance");
// same thing:
trace(foo_instance.toString() + " is the value for foo_instance.toString()");
/* /*
@ -524,8 +526,8 @@ class LearnHaxe3{
*/ */
class FooClass extends BarClass implements BarInterface{ class FooClass extends BarClass implements BarInterface{
public var public_any:Int; // public variables are accessible anywhere public var public_any:Int; // public variables are accessible anywhere
public var public_read (default,null): Int; // use this style to only enable public read public var public_read (default, null): Int; // enable only public read
public var public_write (null, default): Int; // or public write public var public_write (null, default): Int; // or only public write
public var property (get, set): Int; // use this style to enable getters/setters public var property (get, set): Int; // use this style to enable getters/setters
// private variables are not available outside the class. // private variables are not available outside the class.
@ -534,9 +536,10 @@ class FooClass extends BarClass implements BarInterface{
// a public constructor // a public constructor
public function new(arg:Int){ public function new(arg:Int){
super(); // call the constructor of the parent object, since we extended BarClass // call the constructor of the parent object, since we extended BarClass:
super();
this.public_any= 0; this.public_any = 0;
this._private = arg; this._private = arg;
} }

275
it-it/bash-it.html.markdown Normal file
View File

@ -0,0 +1,275 @@
---
category: tool
tool: bash
contributors:
- ["Max Yankov", "https://github.com/golergka"]
- ["Darren Lin", "https://github.com/CogBear"]
- ["Alexandre Medeiros", "http://alemedeiros.sdf.org"]
- ["Denis Arh", "https://github.com/darh"]
- ["akirahirose", "https://twitter.com/akirahirose"]
- ["Anton Strömkvist", "http://lutic.org/"]
- ["Rahil Momin", "https://github.com/iamrahil"]
- ["Gregrory Kielian", "https://github.com/gskielian"]
filename: LearnBash.sh
translators:
- ["Robert Margelli", "http://github.com/sinkswim/"]
lang: it-it
---
Bash è il nome della shell di unix, la quale è stata distribuita anche come shell del sistema oprativo GNU e la shell di default su Linux e Mac OS X.
Quasi tutti gli esempi sottostanti possono fare parte di uno shell script o eseguiti direttamente nella shell.
[Per saperne di piu'.](http://www.gnu.org/software/bash/manual/bashref.html)
```bash
#!/bin/bash
# La prima riga dello script è lo shebang il quale dice al sistema come eseguire
# lo script: http://it.wikipedia.org/wiki/Shabang
# Come avrai già immaginato, i commenti iniziano con #. Lo shebang stesso è un commento.
# Semplice esempio ciao mondo:
echo Ciao mondo!
# Ogni comando inizia su una nuova riga, o dopo un punto e virgola:
echo 'Questa è la prima riga'; echo 'Questa è la seconda riga'
# Per dichiarare una variabile:
VARIABILE="Una stringa"
# Ma non così:
VARIABILE = "Una stringa"
# Bash stabilirà che VARIABILE è un comando da eseguire e darà un errore
# perchè non esiste.
# Usare la variabile:
echo $VARIABILE
echo "$VARIABILE"
echo '$VARIABILE'
# Quando usi la variabile stessa - assegnala, esportala, oppure — scrivi
# il suo nome senza $. Se vuoi usare il valore della variabile, devi usare $.
# Nota che ' (singolo apice) non espande le variabili!
# Sostituzione di stringhe nelle variabili
echo ${VARIABILE/Una/A}
# Questo sostituirà la prima occorrenza di "Una" con "La"
# Sottostringa di una variabile
echo ${VARIABILE:0:7}
# Questo ritornerà solamente i primi 7 caratteri
# Valore di default per la variabile
echo ${FOO:-"ValoreDiDefaultSeFOOMancaOÈ Vuoto"}
# Questo funziona per null (FOO=), stringa vuota (FOO=""), zero (FOO=0) ritorna 0
# Variabili builtin:
# Ci sono delle variabili builtin molto utili, come
echo "Valore di ritorno dell'ultimo programma eseguito: $?"
echo "PID dello script: $$"
echo "Numero di argomenti: $#"
echo "Argomenti dello script: $@"
echo "Argomenti dello script separati in variabili distinte: $1 $2..."
# Leggere un valore di input:
echo "Come ti chiami?"
read NOME # Nota che non abbiamo dovuto dichiarare una nuova variabile
echo Ciao, $NOME!
# Classica struttura if:
# usa 'man test' per maggiori informazioni sulle condizionali
if [ $NOME -ne $USER ]
then
echo "Il tuo nome non è lo username"
else
echo "Il tuo nome è lo username"
fi
# C'è anche l'esecuzione condizionale
echo "Sempre eseguito" || echo "Eseguito solo se la prima condizione fallisce"
echo "Sempre eseguito" && echo "Eseguito solo se la prima condizione NON fallisce"
# Per usare && e || con l'if, c'è bisogno di piu' paia di parentesi quadre:
if [ $NOME == "Steve" ] && [ $ETA -eq 15 ]
then
echo "Questo verrà eseguito se $NOME è Steve E $ETA è 15."
fi
if [ $NOME == "Daniya" ] || [ $NOME == "Zach" ]
then
echo "Questo verrà eseguito se $NAME è Daniya O Zach."
fi
# Le espressioni sono nel seguente formato:
echo $(( 10 + 5 ))
# A differenza di altri linguaggi di programmazione, bash è una shell - quindi lavora nel contesto
# della cartella corrente. Puoi elencare i file e le cartelle nella cartella
# corrente con il comando ls:
ls
# Questi comandi hanno opzioni che controllano la loro esecuzione:
ls -l # Elenca tutti i file e le cartelle su una riga separata
# I risultati del comando precedente possono essere passati al comando successivo come input.
# Il comando grep filtra l'input con il pattern passato. Ecco come possiamo elencare i
# file .txt nella cartella corrente:
ls -l | grep "\.txt"
# Puoi redirezionare l'input e l'output del comando (stdin, stdout, e stderr).
# Leggi da stdin finchè ^EOF$ e sovrascrivi hello.py con le righe
# comprese tra "EOF":
cat > hello.py << EOF
#!/usr/bin/env python
from __future__ import print_function
import sys
print("#stdout", file=sys.stdout)
print("#stderr", file=sys.stderr)
for line in sys.stdin:
print(line, file=sys.stdout)
EOF
# Esegui hello.py con diverse redirezioni stdin, stdout, e stderr:
python hello.py < "input.in"
python hello.py > "output.out"
python hello.py 2> "error.err"
python hello.py > "output-and-error.log" 2>&1
python hello.py > /dev/null 2>&1
# Lo output error sovrascriverà il file se esiste,
# se invece vuoi appendere usa ">>":
python hello.py >> "output.out" 2>> "error.err"
# Sovrascrivi output.txt, appendi a error.err, e conta le righe:
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
wc -l output.out error.err
# Esegui un comando e stampa il suo file descriptor (esempio: /dev/fd/123)
# vedi: man fd
echo <(echo "#ciaomondo")
# Sovrascrivi output.txt con "#helloworld":
cat > output.out <(echo "#helloworld")
echo "#helloworld" > output.out
echo "#helloworld" | cat > output.out
echo "#helloworld" | tee output.out >/dev/null
# Pulisci i file temporanei verbosamente (aggiungi '-i' per la modalità interattiva)
rm -v output.out error.err output-and-error.log
# I comandi possono essere sostituiti con altri comandi usando $( ):
# Il comando seguente mostra il numero di file e cartelle nella
# cartella corrente.
echo "Ci sono $(ls | wc -l) oggetti qui."
# Lo stesso puo' essere usato usando backticks `` ma non possono essere innestati - il modo migliore
# è usando $( ).
echo "Ci sono `ls | wc -l` oggetti qui."
# Bash utilizza uno statemente case che funziona in maniera simile allo switch in Java e C++:
case "$VARIABILE" in
#Lista di pattern per le condizioni che vuoi soddisfare
0) echo "C'è uno zero.";;
1) echo "C'è un uno.";;
*) echo "Non è null.";;
esac
# I cicli for iterano per ogni argomento fornito:
# I contenuti di $VARIABILE sono stampati tre volte.
for VARIABILE in {1..3}
do
echo "$VARIABILE"
done
# O scrivilo con il "ciclo for tradizionale":
for ((a=1; a <= 3; a++))
do
echo $a
done
# Possono essere usati anche per agire su file..
# Questo eseguirà il comando 'cat' su file1 e file2
for VARIABILE in file1 file2
do
cat "$VARIABILE"
done
# ..o dall'output di un comando
# Questo eseguirà cat sull'output di ls.
for OUTPUT in $(ls)
do
cat "$OUTPUT"
done
# while loop:
while [ true ]
do
echo "corpo del loop..."
break
done
# Puoi anche definire funzioni
# Definizione:
function foo ()
{
echo "Gli argomenti funzionano come gli argomenti dello script: $@"
echo "E: $1 $2..."
echo "Questa è una funzione"
return 0
}
# o semplicemente
bar ()
{
echo "Un altro modo per dichiarare funzioni!"
return 0
}
# Per chiamare la funzione
foo "Il mio nome è" $NOME
# Ci sono un sacco di comandi utili che dovresti imparare:
# stampa le ultime 10 righe di file.txt
tail -n 10 file.txt
# stampa le prime 10 righe di file.txt
head -n 10 file.txt
# ordina le righe di file.txt
sort file.txt
# riporta o ometti le righe ripetute, con -d le riporta
uniq -d file.txt
# stampa solamente la prima colonna prima del carattere ','
cut -d ',' -f 1 file.txt
# sostituisce ogni occorrenza di 'okay' con 'great' in file.txt (compatible con le regex)
sed -i 's/okay/great/g' file.txt
# stampa su stdout tutte le righe di file.txt che soddisfano una certa regex
# L'esempio stampa le righe che iniziano con "foo" e che finiscono con "bar"
grep "^foo.*bar$" file.txt
# passa l'opzione "-c" per stampare invece il numero delle righe che soddisfano la regex
grep -c "^foo.*bar$" file.txt
# se vuoi letteralmente cercare la stringa,
# e non la regex, usa fgrep (o grep -F)
fgrep "^foo.*bar$" file.txt
# Leggi la documentazione dei builtin di bash con il builtin 'help' di bash:
help
help help
help for
help return
help source
help .
# Leggi la manpage di bash con man
apropos bash
man 1 bash
man bash
# Leggi la documentazione con info (? per help)
apropos info | grep '^info.*('
man info
info info
info 5 info
# Leggi la documentazione di bash:
info bash
info bash 'Bash Features'
info bash 6
info --apropos bash
```

720
it-it/c++-it.html.markdown Normal file
View File

@ -0,0 +1,720 @@
---
language: c++
filename: learncpp-it.cpp
contributors:
- ["Steven Basart", "http://github.com/xksteven"]
- ["Matt Kline", "https://github.com/mrkline"]
translators:
- ["Robert Margelli", "http://github.com/sinkswim/"]
lang: it-it
---
Il C++ è un linguaggio di programmazione il quale,
[secondo il suo inventore Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
è stato progettato per
- essere un "miglior C"
- supportare l'astrazione dei dati
- supportare la programmazione orientata agli oggetti
- supportare la programmazione generica
Nonostante la sintassi possa risultare più difficile o complessa di linguaggi più recenti,
è usato in maniera vasta poichè viene compilato in istruzioni macchina che possono
essere eseguite direttamente dal processore ed offre un controllo stretto sull'hardware (come il linguaggio C)
ed allo stesso tempo offre caratteristiche ad alto livello come i generici, le eccezioni, e le classi.
Questa combinazione di velocità e funzionalità rende il C++
uno dei più utilizzati linguaggi di programmazione.
```c++
//////////////////
// Confronto con il C
//////////////////
// Il C++ è _quasi_ un superset del C e con esso condivide la sintassi di base per
// la dichiarazione di variabili, tipi primitivi, e funzioni.
// Proprio come nel C, l'inizio del programma è una funzione chiamata
// main con un intero come tipo di ritorno,
// Questo valore serve come stato d'uscita del programma.
// Vedi http://it.wikipedia.org/wiki/Valore_di_uscita per maggiori informazioni.
int main(int argc, char** argv)
{
// Gli argomenti a linea di comando sono passati tramite argc e argv così come
// avviene in C.
// argc indica il numero di argomenti,
// e argv è un array di stringhe in stile-C (char*)
// che rappresenta gli argomenti.
// Il primo argomento è il nome che è stato assegnato al programma.
// argc e argv possono essere omessi se non hai bisogno di argomenti,
// in questa maniera la funzione avrà int main() come firma.
// Lo stato di uscita 0 indica successo.
return 0;
}
// Tuttavia, il C++ varia nei seguenti modi:
// In C++, i caratteri come letterali sono da un byte.
sizeof('c') == 1
// In C, i caratteri come letterali sono della stessa dimensione degli interi.
sizeof('c') == sizeof(10)
// C++ ha prototipizzazione rigida
void func(); // funziona che non accetta argomenti
// In C
void func(); // funzione che può accettare un qualsiasi numero di argomenti
// Usa nullptr invece di NULL in C++
int* ip = nullptr;
// Gli header C standard sono disponibili in C++,
// ma sono prefissati con "c" e non hanno il suffisso ".h".
#include <cstdio>
int main()
{
printf("Ciao, mondo!\n");
return 0;
}
///////////////////////////////
// Overloading per le funzioni
//////////////////////////////
// Il C++ supporta l'overloading per le funzioni
// sia dato che ogni funzione accetta parametri diversi.
void print(char const* myString)
{
printf("Stringa %s\n", myString);
}
void print(int myInt)
{
printf("Il mio int è %d", myInt);
}
int main()
{
print("Ciao"); // Viene chiamata void print(const char*)
print(15); // Viene chiamata void print(int)
}
////////////////////////
// Argomenti di default
///////////////////////
// Puoi fornire argomenti di default per una funzione
// se non sono forniti dal chiamante.
void faiQualcosaConInteri(int a = 1, int b = 4)
{
// fai qualcosa con gli interi qui
}
int main()
{
faiQualcosaConInteri(); // a = 1, b = 4
faiQualcosaConInteri(20); // a = 20, b = 4
faiQualcosaConInteri(20, 5); // a = 20, b = 5
}
// Gli argomenti di default devono essere alla fine della lista degli argomenti.
void dichiarazioneInvalida(int a = 1, int b) // Errore!
{
}
/////////////
// Namespaces
/////////////
// I namespaces forniscono visibilità separata per dichiarazioni di variabili, funzioni,
// ed altro.
// I namespaces possono essere annidati.
namespace Primo {
namespace Annidato {
void foo()
{
printf("Questa è Primo::Annidato::foo\n");
}
} // fine di namespace Annidato
} // fine di namespace Primo
namespace Secondo {
void foo()
{
printf("Questa è Secondo::foo\n")
}
}
void foo()
{
printf("Questa è foo globale\n");
}
int main()
{
// Assume che tutto venga dal namespace "Secondo"
// a meno che non venga dichiarato altrimenti.
using namespace Secondo;
foo(); // stampa "Questa è Secondo::foo"
Primo::Annidato::foo(); // stampa "Questa è Primo::Annidato::foo"
::foo(); // stampa "Questa è foo globale"
}
///////////////
// Input/Output
///////////////
// L'input e l'output in C++ utilizza gli streams
// cin, cout, e cerr i quali rappresentano stdin, stdout, e stderr.
// << è l'operatore di inserzione >> è l'operatore di estrazione.
#include <iostream> // Include gli streams di I/O
using namespace std; // Gli streams sono nel namespace std (libreria standard)
int main()
{
int myInt;
// Stampa su stdout (o terminalee/schermo)
cout << "Inserisci il tuo numero preferito:\n";
// Prende l'input
cin >> myInt;
// cout può anche essere formattato
cout << "Il tuo numero preferito è " << myInt << "\n";
// stampa "Il tuo numero preferito è <myInt>"
cerr << "Usato per messaggi di errore";
}
////////////
// Stringhe
///////////
// Le stringhe in C++ sono oggetti ed hanno molte funzioni membro
#include <string>
using namespace std; // Anche le stringhe sono contenute nel namespace std (libreria standard)
string myString = "Ciao";
string myOtherString = " Mondo";
// + è usato per la concatenazione.
cout << myString + myOtherString; // "Ciao Mondo"
cout << myString + " Bella"; // "Ciao Bella"
// le stringhe in C++ possono essere modificate.
myString.append(" Mario");
cout << myString; // "Ciao Mario"
///////////////
// Riferimenti
//////////////
// Oltre ai puntatori come quelli in C,
// il C++ ha i _riferimenti_.
// Questi non sono tipi puntatori che non possono essere riassegnati una volta settati
// e non possono essere null.
// Inoltre, essi hanno la stessa sintassi della variabile stessa:
// * non è necessario per la dereferenziazione e
// & ("indirizzo di") non è usato per l'assegnamento.
using namespace std;
string foo = "Io sono foo";
string bar = "Io sono bar";
string& fooRef = foo; // Questo crea un riferimento a foo.
fooRef += ". Ciao!"; // Modifica foo attraverso il riferimento
cout << fooRef; // Stampa "Io sono foo. Ciao!"
// Non riassegna "fooRef". Questo è come scrivere "foo = bar", e
// foo == "Io sono bar"
// dopo questa riga.
fooRef = bar;
const string& barRef = bar; // Crea un riferimento const a bar.
// Come in C, i valori const (i puntatori e i riferimenti) non possono essere modificati.
barRef += ". Ciao!"; // Errore, i riferimenti const non possono essere modificati.
//////////////////////////////////////////////////
// Classi e programmazione orientata agli oggetti
/////////////////////////////////////////////////
// Primo esempio delle classi
#include <iostream>
// Dichiara una classe.
// Le classi sono in genere dichiara in un header file (.h o .hpp).
class Cane {
// Variabili e funzioni membro sono private di default.
std::string nome;
int peso;
// Tutti i membri dopo questo sono pubblici (public)
// finchè "private:" o "protected:" non compaiono.
public:
// Costruttore di default
Cane();
// Dichiarazioni di funzioni membro (le implentazioni sono a seguito)
// Nota che stiamo usando std::string invece di porre
// using namespace std;
// sopra.
// Mai usare uno statement "using namespace" in uno header.
void impostaNome(const std::string& nomeCane);
void impostaPeso(int pesoCane);
// Le funzioni che non modificano lo stato dell'oggetto
// dovrebbero essere marcate come const.
// Questo permette di chiamarle con un riferimento const all'oggetto.
// Inoltre, nota che le funzioni devono essere dichiarate espliciamente come _virtual_
// per essere sovrascritte in classi derivate.
// Le funzioni non sono virtual di default per motivi di performance.
virtual void print() const;
// Le funzioni possono essere definite anche all'interno del corpo della classe.
// Le funzioni definite in questo modo sono automaticamente inline.
void abbaia() const { std::cout << nome << " abbaia!\n"; }
// Assieme con i costruttori, il C++ fornisce i distruttori.
// Questi sono chiamati quando un oggetto è rimosso o esce dalla visibilità.
// Questo permette paradigmi potenti come il RAII
// (vedi sotto)
// I distruttori devono essere virtual per permettere a classi di essere derivate da questa.
virtual ~Dog();
}; // Un punto e virgola deve seguire la definizione della funzione
// Le funzioni membro di una classe sono generalmente implementate in files .cpp .
void Cane::Cane()
{
std::cout << "Un cane è stato costruito\n";
}
// Gli oggetti (ad esempio le stringhe) devono essere passati per riferimento
// se li stai modificando o come riferimento const altrimenti.
void Cane::impostaNome(const std::string& nomeCane)
{
nome = nomeCane;
}
void Cane::impostaPeso(int pesoCane)
{
peso = pesoCane;
}
// Notare che "virtual" è solamente necessario nelle dichiarazioni, non nelle definizioni.
void Cane::print() const
{
std::cout << "Il cane è " << nome << " e pesa " << peso << "kg\n";
}
void Cane::~Cane()
{
cout << "Ciao ciao " << nome << "\n";
}
int main() {
Cane myDog; // stampa "Un cane è stato costruito"
myDog.impostaNome("Barkley");
myDog.impostaPeso(10);
myDog.print(); // stampa "Il cane è Barkley e pesa 10 kg"
return 0;
} // stampa "Ciao ciao Barkley"
// Ereditarietà:
// Questa classe eredita tutto ciò che è public e protected dalla classe Cane
class MioCane : public Cane {
void impostaProprietario(const std::string& proprietarioCane)
// Sovrascrivi il comportamento della funzione print per tutti i MioCane. Vedi
// http://it.wikipedia.org/wiki/Polimorfismo_%28informatica%29
// per una introduzione più generale se non sei familiare con
// il polimorfismo.
// La parola chiave override è opzionale ma fa sì che tu stia effettivamente
// sovrascrivendo il metodo nella classe base.
void print() const override;
private:
std::string proprietario;
};
// Nel frattempo, nel file .cpp corrispondente:
void MioCane::impostaProprietario(const std::string& proprietarioCane)
{
proprietario = proprietarioCane;
}
void MioCane::print() const
{
Cane::print(); // Chiama la funzione print nella classe base Cane
std::cout << "Il cane è di " << proprietario << "\n";
// stampa "Il cane è <nome> e pesa <peso>"
// "Il cane è di <proprietario>"
}
///////////////////////////////////////////////////
// Inizializzazione ed Overloading degli Operatori
//////////////////////////////////////////////////
// In C++ puoi sovrascrivere il comportamento di operatori come +, -, *, /, ecc...
// Questo è possibile definendo una funzione che viene chiamata
// ogniqualvolta l'operatore è usato.
#include <iostream>
using namespace std;
class Punto {
public:
// Così si assegna alle variabili membro un valore di default.
double x = 0;
double y = 0;
// Definisce un costruttore di default che non fa nulla
// ma inizializza il Punto ai valori di default (0, 0)
Punto() { };
// La sintassi seguente è nota come lista di inizializzazione
// ed è il modo appropriato di inizializzare i valori membro della classe
Punto (double a, double b) :
x(a),
y(b)
{ /* Non fa nulla eccetto inizializzare i valori */ }
// Sovrascrivi l'operatore +.
Punto operator+(const Punto& rhs) const;
// Sovrascrivi l'operatore +=
Punto& operator+=(const Punto& rhs);
// Avrebbe senso aggiungere gli operatori - e -=,
// ma li saltiamo per rendere la guida più breve.
};
Punto Punto::operator+(const Punto& rhs) const
{
// Crea un nuovo punto come somma di questo e di rhs.
return Punto(x + rhs.x, y + rhs.y);
}
Punto& Punto::operator+=(const Punto& rhs)
{
x += rhs.x;
y += rhs.y;
return *this;
}
int main () {
Punto su (0,1);
Punto destro (1,0);
// Questo chiama l'operatore + di Punto
// Il Punto su chiama la funzione + con destro come argomento
Punto risultato = su + destro;
// Stampa "Risultato è spostato in (1,1)"
cout << "Risultato è spostato (" << risultato.x << ',' << risultato.y << ")\n";
return 0;
}
/////////////////
// Templates
////////////////
// Generalmente i templates in C++ sono utilizzati per programmazione generica, anche se
// sono molto più potenti dei costrutti generici in altri linguaggi. Inoltre,
// supportano specializzazione esplicita e parziale, classi in stile funzionale,
// e sono anche complete per Turing.
// Iniziamo con il tipo di programmazione generica con cui forse sei familiare. Per
// definire una classe o una funzione che prende un parametro di un dato tipo:
template<class T>
class Box {
// In questa classe, T può essere usato come qualsiasi tipo.
void inserisci(const T&) { ... }
};
// Durante la compilazione, il compilatore in effetti genera copie di ogni template
// con i parametri sostituiti, e così la definizione completa della classe deve essere
// presente ad ogni invocazione. Questo è il motivo per cui vedrai le classi template definite
// interamente in header files.
// Per instanziare una classe template sullo stack:
Box<int> intBox;
// e puoi usarla come aspettato:
intBox.inserisci(123);
//Puoi, ovviamente, innestare i templates:
Box<Box<int> > boxOfBox;
boxOfBox.inserisci(intBox);
// Fino al C++11, devi porre uno spazio tra le due '>', altrimenti '>>'
// viene visto come l'operatore di shift destro.
// Qualche volta vedrai
// template<typename T>
// invece. La parole chiavi 'class' e 'typename' sono _generalmente_
// intercambiabili in questo caso. Per una spiegazione completa, vedi
// http://en.wikipedia.org/wiki/Typename
// (si, quella parola chiave ha una sua pagina di Wikipedia propria).
// Similmente, una funzione template:
template<class T>
void abbaiaTreVolte(const T& input)
{
input.abbaia();
input.abbaia();
input.abbaia();
}
// Nota che niente è specificato relativamente al tipo di parametri. Il compilatore
// genererà e poi verificherà il tipo di ogni invocazione del template, così che
// la funzione di cui sopra funzione con ogni tipo 'T' che ha const 'abbaia' come metodo!
Cane fluffy;
fluffy.impostaNome("Fluffy")
abbaiaTreVolte(fluffy); // Stampa "Fluffy abbaia" tre volte.
// I parametri template non devono essere classi:
template<int Y>
void stampaMessaggio() {
cout << "Impara il C++ in " << Y << " minuti!" << endl;
}
// E poi esplicitamente specializzare i template per avere codice più efficiente. Ovviamente,
// la maggior parte delle casistiche reali non sono così triviali.
// Notare che avrai comunque bisogna di dichiarare la funzione (o classe) come un template
// anche se hai esplicitamente specificato tutti i parametri.
template<>
void stampaMessaggio<10>() {
cout << "Impara il C++ più velocemente in soli 10 minuti!" << endl;
}
printMessage<20>(); // Stampa "impara il C++ in 20 minuti!"
printMessage<10>(); // Stampa "Impara il C++ più velocemente in soli 10 minuti!"
////////////////////////////
// Gestione delle eccezioni
///////////////////////////
// La libreria standard fornisce un paio di tipi d'eccezioni
// (vedi http://en.cppreference.com/w/cpp/error/exception)
// ma ogni tipo può essere lanciato come eccezione
#include <exception>
// Tutte le eccezioni lanciate all'interno del blocco _try_ possono essere catturate dai successivi
// handlers _catch_.
try {
// Non allocare eccezioni nello heap usando _new_.
throw std::exception("È avvenuto un problema");
}
// Cattura le eccezioni come riferimenti const se sono oggetti
catch (const std::exception& ex)
{
std::cout << ex.what();
// Cattura ogni eccezioni non catturata dal blocco _catch_ precedente
} catch (...)
{
std::cout << "Catturata un'eccezione sconosciuta";
throw; // Rilancia l'eccezione
}
///////
// RAII
///////
// RAII sta per Resource Allocation Is Initialization.
// Spesso viene considerato come il più potente paradigma in C++.
// È un concetto semplice: un costruttore di un oggetto
// acquisisce le risorse di tale oggetto ed il distruttore le rilascia.
// Per comprendere come questo sia vantaggioso,
// consideriamo una funzione che usa un gestore di file in C:
void faiQualcosaConUnFile(const char* nomefile)
{
// Per cominciare, assumiamo che niente possa fallire.
FILE* fh = fopen(nomefile, "r"); // Apri il file in modalità lettura.
faiQualcosaConIlFile(fh);
faiQualcosAltroConEsso(fh);
fclose(fh); // Chiudi il gestore di file.
}
// Sfortunatamente, le cose vengono complicate dalla gestione degli errori.
// Supponiamo che fopen fallisca, e che faiQualcosaConUnFile e
// faiQualcosAltroConEsso ritornano codici d'errore se falliscono.
// (Le eccezioni sono la maniera preferita per gestire i fallimenti,
// ma alcuni programmatori, specialmente quelli con un passato in C,
// non sono d'accordo con l'utilità delle eccezioni).
// Adesso dobbiamo verificare che ogni chiamata per eventuali fallimenti e chiudere il gestore di file
// se un problema è avvenuto.
bool faiQualcosaConUnFile(const char* nomefile)
{
FILE* fh = fopen(nomefile, "r"); // Apre il file in modalità lettura
if (fh == nullptr) // Il puntatore restituito è null in caso di fallimento.
return false; // Riporta il fallimento al chiamante.
// Assumiamo che ogni funzione ritorni false se ha fallito
if (!faiQualcosaConIlFile(fh)) {
fclose(fh); // Chiude il gestore di file così che non sprechi memoria.
return false; // Propaga l'errore.
}
if (!faiQualcosAltroConEsso(fh)) {
fclose(fh); // Chiude il gestore di file così che non sprechi memoria.
return false; // Propaga l'errore.
}
fclose(fh); // Chiudi il gestore di file così che non sprechi memoria.
return true; // Indica successo
}
// I programmatori C in genere puliscono questa procedura usando goto:
bool faiQualcosaConUnFile(const char* nomefile)
{
FILE* fh = fopen(nomefile, "r");
if (fh == nullptr)
return false;
if (!faiQualcosaConIlFile(fh))
goto fallimento;
if (!faiQualcosAltroConEsso(fh))
goto fallimento;
fclose(fh); // Chiude il file
return true; // Indica successo
fallimento:
fclose(fh);
return false; // Propaga l'errore
}
// Se le funzioni indicano errori usando le eccezioni,
// le cose sono un pò più pulite, ma sono sempre sub-ottimali.
void faiQualcosaConUnFile(const char* nomefile)
{
FILE* fh = fopen(nomefile, "r"); // Apre il file in modalità lettura
if (fh == nullptr)
throw std::exception("Non è stato possibile aprire il file.").
try {
faiQualcosaConIlFile(fh);
faiQualcosAltroConEsso(fh);
}
catch (...) {
fclose(fh); // Fai sì che il file venga chiuso se si ha un errore.
throw; // Poi rilancia l'eccezione.
}
fclose(fh); // Chiudi il file
// Tutto è andato bene
}
// Confronta questo con l'utilizzo della classe C++ file stream (fstream)
// fstream usa i distruttori per chiudere il file.
// Come detto sopra, i distruttori sono automaticamente chiamati
// ogniqualvolta un oggetto esce dalla visibilità.
void faiQualcosaConUnFile(const std::string& nomefile)
{
// ifstream è l'abbreviazione di input file stream
std::ifstream fh(nomefile); // Apre il file
// Fai qualcosa con il file
faiQualcosaConIlFile(fh);
faiQualcosAltroConEsso(fh);
} // Il file viene chiuso automaticamente chiuso qui dal distruttore
// Questo ha vantaggi _enormi_:
// 1. Può succedere di tutto ma
// la risorsa (in questo caso il file handler) verrà ripulito.
// Una volta che scrivi il distruttore correttamente,
// È _impossibile_ scordarsi di chiudere l'handler e sprecare memoria.
// 2. Nota che il codice è molto più pulito.
// Il distruttore gestisce la chiusura del file dietro le scene
// senza che tu debba preoccupartene.
// 3. Il codice è sicuro da eccezioni.
// Una eccezione può essere lanciata in qualunque punto nella funzione e la ripulitura
// avverrà lo stesso.
// Tutto il codice C++ idiomatico usa RAII in maniera vasta su tutte le risorse.
// Esempi aggiuntivi includono
// - Utilizzo della memoria con unique_ptr e shared_ptr
// - I contenitori - la lista della libreria standard,
// vettori (i.e. array auto-aggiustati), mappe hash, e così via
// sono tutti automaticamente distrutti con i loro contenuti quando escono dalla visibilità.
// - I mutex usano lock_guard e unique_lock
///////////////////////
// Roba divertente
//////////////////////
// Aspetti del C++ che potrebbero sbalordire i nuovi arrivati (e anche qualche veterano).
// Questa sezione è, sfortunatamente, selvaggiamente incompleta; il C++ è uno dei linguaggi
// più facili con cui puoi spararti da solo nel piede.
// Puoi sovrascrivere metodi privati!
class Foo {
virtual void bar();
};
class FooSub : public Foo {
virtual void bar(); // sovrascrive Foo::bar!
};
// 0 == false == NULL (la maggior parte delle volte)!
bool* pt = new bool;
*pt = 0; // Setta il valore puntato da 'pt' come falso.
pt = 0; // Setta 'pt' al puntatore null. Entrambe le righe vengono compilate senza warnings.
// nullptr dovrebbe risolvere alcune di quei problemi:
int* pt2 = new int;
*pt2 = nullptr; // Non compila
pt2 = nullptr; // Setta pt2 a null.
// Ma in qualche modo il tipo 'bool' è una eccezione (questo è per rendere compilabile `if (ptr)`.
*pt = nullptr; // Questo compila, anche se '*pt' è un bool!
// '=' != '=' != '='!
// Chiama Foo::Foo(const Foo&) o qualche variante del costruttore di copia.
Foo f2;
Foo f1 = f2;
// Chiama Foo::Foo(const Foo&) o qualche variante, ma solo copie di 'Foo' che fanno parte di
// 'fooSub'. Ogni altro membro di 'fooSub' viene scartato. Questo comportamento
// orribile viene chiamato "object slicing."
FooSub fooSub;
Foo f1 = fooSub;
// Chiama Foo::operator=(Foo&) o una sua variante.
Foo f1;
f1 = f2;
```
Letture consigliate:
Un riferimento aggiornato del linguaggio può essere trovato qui
<http://cppreference.com/w/cpp>
Risorse addizionali possono essere trovate qui <http://cplusplus.com>

View File

@ -0,0 +1,62 @@
---
language: json
contributors:
- ["Anna Harren", "https://github.com/iirelu"]
- ["Marco Scannadinari", "https://github.com/marcoms"]
translators:
- ["Robert Margelli", "http://github.com/sinkswim/"]
lang: it-it
---
Dato che JSON è un formato per lo scambio di dati estremamente semplice, questo sarà con molta probabilità
il più semplice Learn X in Y Minutes.
Nella sua forma più pura JSON non ha commenti, ma molti parser accettano
commenti in stile C (//, /\* \*/). Per lo scopo prefissato, tuttavia, tutto sarà
100% JSON valido. Fortunatamente, si spiega da sè.
```json
{
"chiave": "valore",
"chiavi": "devono sempre essere racchiuse tra doppi apici",
"numeri": 0,
"stringhe": "Ciaø, møndø. Tutti gli unicode sono permessi, assieme con l \"escaping\".",
"ha booleani?": true,
"il nulla": null,
"numero grande": 1.2e+100,
"oggetti": {
"commento": "La maggior parte della tua struttura viene dagli oggetti.",
"array": [0, 1, 2, 3, "Gli array possono contenere qualsiasi cosa.", 5],
"un altro oggetto": {
"commento": "Queste cose possono essere annidate, molto utile."
}
},
"sciocchezze": [
{
"sorgenti di potassio": ["banane"]
},
[
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, "neo"],
[0, 0, 0, 1]
]
],
"stile alternativo": {
"commento": "Guarda quà!"
, "posizione della virgola": "non conta - fintantochè è prima del valore, allora è valida"
, "un altro commento": "che bello"
},
"è stato molto breve": "Ed hai finito. Adesso sai tutto cio che JSON ha da offrire."
}
```

View File

@ -1,16 +1,16 @@
--- ---
language: java language: java
contributors: contributors:
- ["Jake Prather", "http://github.com/JakeHP"] - ["Jake Prather", "http://github.com/JakeHP"]
- ["Madison Dickson", "http://github.com/mix3d"]
- ["Jakukyo Friel", "http://weakish.github.io"] - ["Jakukyo Friel", "http://weakish.github.io"]
- ["Madison Dickson", "http://github.com/mix3d"]
- ["Simon Morgan", "http://sjm.io/"]
filename: LearnJava.java filename: LearnJava.java
--- ---
Java is a general-purpose, concurrent, class-based, object-oriented computer programming language. Java is a general-purpose, concurrent, class-based, object-oriented computer
[Read more here.](http://docs.oracle.com/javase/tutorial/java/index.html) programming language.
[Read more here.](http://docs.oracle.com/javase/tutorial/java/)
```java ```java
// Single-line comments start with // // Single-line comments start with //
@ -31,17 +31,17 @@ import java.security.*;
// the file. // the file.
public class LearnJava { public class LearnJava {
// A program must have a main method as an entry point // A program must have a main method as an entry point.
public static void main (String[] args) { public static void main (String[] args) {
// Use System.out.println to print lines // Use System.out.println() to print lines.
System.out.println("Hello World!"); System.out.println("Hello World!");
System.out.println( System.out.println(
"Integer: " + 10 + "Integer: " + 10 +
" Double: " + 3.14 + " Double: " + 3.14 +
" Boolean: " + true); " Boolean: " + true);
// To print without a newline, use System.out.print // To print without a newline, use System.out.print().
System.out.print("Hello "); System.out.print("Hello ");
System.out.print("World"); System.out.print("World");
@ -69,7 +69,7 @@ public class LearnJava {
// L is used to denote that this variable value is of type Long; // L is used to denote that this variable value is of type Long;
// anything without is treated as integer by default. // anything without is treated as integer by default.
// Note: Java has no unsigned types // Note: Java has no unsigned types.
// Float - Single-precision 32-bit IEEE 754 Floating Point // Float - Single-precision 32-bit IEEE 754 Floating Point
float fooFloat = 234.5f; float fooFloat = 234.5f;
@ -86,7 +86,7 @@ public class LearnJava {
// Char - A single 16-bit Unicode character // Char - A single 16-bit Unicode character
char fooChar = 'A'; char fooChar = 'A';
// final variables can't be reassigned to another object // final variables can't be reassigned to another object.
final int HOURS_I_WORK_PER_WEEK = 9001; final int HOURS_I_WORK_PER_WEEK = 9001;
// Strings // Strings
@ -101,10 +101,10 @@ public class LearnJava {
System.out.println(bazString); System.out.println(bazString);
// Arrays // Arrays
//The array size must be decided upon instantiation // The array size must be decided upon instantiation
//The following formats work for declaring an array // The following formats work for declaring an array
//<datatype>[] <var name> = new <datatype>[<array size>]; // <datatype>[] <var name> = new <datatype>[<array size>];
//<datatype> <var name>[] = new <datatype>[<array size>]; // <datatype> <var name>[] = new <datatype>[<array size>];
int[] intArray = new int[10]; int[] intArray = new int[10];
String[] stringArray = new String[1]; String[] stringArray = new String[1];
boolean boolArray[] = new boolean[100]; boolean boolArray[] = new boolean[100];
@ -122,17 +122,17 @@ public class LearnJava {
System.out.println("intArray @ 1: " + intArray[1]); // => 1 System.out.println("intArray @ 1: " + intArray[1]); // => 1
// Others to check out // Others to check out
// ArrayLists - Like arrays except more functionality is offered, // ArrayLists - Like arrays except more functionality is offered, and
// and the size is mutable // the size is mutable.
// LinkedLists - Implementation of doubly-linked list. All of the // LinkedLists - Implementation of doubly-linked list. All of the
// operations perform as could be expected for // operations perform as could be expected for a
// a doubly-linked list. // doubly-linked list.
// Maps - A set of objects that maps keys to values. A map cannot contain // Maps - A set of objects that maps keys to values. A map cannot
// duplicate keys; each key can map to at most one value. // contain duplicate keys; each key can map to at most one value.
// HashMaps - This class uses a hashtable to implement the Map interface. // HashMaps - This class uses a hashtable to implement the Map
// This allows the execution time of basic operations, // interface. This allows the execution time of basic
// such as get and insert element, to remain constant even // operations, such as get and insert element, to remain
// for large sets. // constant even for large sets.
/////////////////////////////////////// ///////////////////////////////////////
// Operators // Operators
@ -160,13 +160,13 @@ public class LearnJava {
// Bitwise operators! // Bitwise operators!
/* /*
~ Unary bitwise complement ~ Unary bitwise complement
<< Signed left shift << Signed left shift
>> Signed right shift >> Signed right shift
>>> Unsigned right shift >>> Unsigned right shift
& Bitwise AND & Bitwise AND
^ Bitwise exclusive OR ^ Bitwise exclusive OR
| Bitwise inclusive OR | Bitwise inclusive OR
*/ */
// Incrementations // Incrementations
@ -175,10 +175,10 @@ public class LearnJava {
// The ++ and -- operators increment and decrement by 1 respectively. // The ++ and -- operators increment and decrement by 1 respectively.
// If they are placed before the variable, they increment then return; // If they are placed before the variable, they increment then return;
// after the variable they return then increment. // after the variable they return then increment.
System.out.println(i++); //i = 1, prints 0 (post-increment) System.out.println(i++); // i = 1, prints 0 (post-increment)
System.out.println(++i); //i = 2, prints 2 (pre-increment) System.out.println(++i); // i = 2, prints 2 (pre-increment)
System.out.println(i--); //i = 1, prints 2 (post-decrement) System.out.println(i--); // i = 1, prints 2 (post-decrement)
System.out.println(--i); //i = 0, prints 0 (pre-decrement) System.out.println(--i); // i = 0, prints 0 (pre-decrement)
/////////////////////////////////////// ///////////////////////////////////////
// Control Structures // Control Structures
@ -197,73 +197,69 @@ public class LearnJava {
// While loop // While loop
int fooWhile = 0; int fooWhile = 0;
while(fooWhile < 100) while(fooWhile < 100) {
{ System.out.println(fooWhile);
//System.out.println(fooWhile); // Increment the counter
//Increment the counter // Iterated 100 times, fooWhile 0,1,2...99
//Iterated 100 times, fooWhile 0,1,2...99
fooWhile++; fooWhile++;
} }
System.out.println("fooWhile Value: " + fooWhile); System.out.println("fooWhile Value: " + fooWhile);
// Do While Loop // Do While Loop
int fooDoWhile = 0; int fooDoWhile = 0;
do do {
{ System.out.println(fooDoWhile);
//System.out.println(fooDoWhile); // Increment the counter
//Increment the counter // Iterated 99 times, fooDoWhile 0->99
//Iterated 99 times, fooDoWhile 0->99
fooDoWhile++; fooDoWhile++;
}while(fooDoWhile < 100); } while(fooDoWhile < 100);
System.out.println("fooDoWhile Value: " + fooDoWhile); System.out.println("fooDoWhile Value: " + fooDoWhile);
// For Loop // For Loop
int fooFor; int fooFor;
//for loop structure => for(<start_statement>; <conditional>; <step>) // for loop structure => for(<start_statement>; <conditional>; <step>)
for(fooFor=0; fooFor<10; fooFor++){ for (fooFor = 0; fooFor < 10; fooFor++) {
//System.out.println(fooFor); System.out.println(fooFor);
//Iterated 10 times, fooFor 0->9 // Iterated 10 times, fooFor 0->9
} }
System.out.println("fooFor Value: " + fooFor); System.out.println("fooFor Value: " + fooFor);
// For Each Loop // For Each Loop
// An automatic iteration through an array or list of objects. // The for loop is also able to iterate over arrays as well as objects
int[] fooList = {1,2,3,4,5,6,7,8,9}; // that implement the Iterable interface.
//for each loop structure => for(<object> : <array_object>) int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
//reads as: for each object in the array // for each loop structure => for (<object> : <iterable>)
//note: the object type must match the array. // reads as: for each element in the iterable
// note: the object type must match the element type of the iterable.
for( int bar : fooList ){ for (int bar : fooList) {
//System.out.println(bar); System.out.println(bar);
//Iterates 9 times and prints 1-9 on new lines //Iterates 9 times and prints 1-9 on new lines
} }
// Switch Case // Switch Case
// A switch works with the byte, short, char, and int data types. // A switch works with the byte, short, char, and int data types.
// It also works with enumerated types (discussed in Enum Types), // It also works with enumerated types (discussed in Enum Types), the
// the String class, and a few special classes that wrap // String class, and a few special classes that wrap primitive types:
// primitive types: Character, Byte, Short, and Integer. // Character, Byte, Short, and Integer.
int month = 3; int month = 3;
String monthString; String monthString;
switch (month){ switch (month) {
case 1: case 1: monthString = "January";
monthString = "January";
break; break;
case 2: case 2: monthString = "February";
monthString = "February";
break; break;
case 3: case 3: monthString = "March";
monthString = "March";
break;
default:
monthString = "Some other month";
break; break;
default: monthString = "Some other month";
break;
} }
System.out.println("Switch Case Result: " + monthString); System.out.println("Switch Case Result: " + monthString);
// Conditional Shorthand // Conditional Shorthand
// You can use the '?' operator for quick assignments or logic forks. // You can use the '?' operator for quick assignments or logic forks.
// Reads as "If (statement) is true, use <first value>, otherwise, use <second value>" // Reads as "If (statement) is true, use <first value>, otherwise, use
// <second value>"
int foo = 5; int foo = 5;
String bar = (foo < 10) ? "A" : "B"; String bar = (foo < 10) ? "A" : "B";
System.out.println(bar); // Prints A, because the statement is true System.out.println(bar); // Prints A, because the statement is true
@ -287,9 +283,8 @@ public class LearnJava {
// String // String
// Typecasting // Typecasting
// You can also cast java objects, there's a lot of details and // You can also cast Java objects, there's a lot of details and deals
// deals with some more intermediate concepts. // with some more intermediate concepts. Feel free to check it out here:
// Feel free to check it out here:
// http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html // http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
@ -319,9 +314,9 @@ public class LearnJava {
// Class Declaration Syntax: // Class Declaration Syntax:
// <public/private/protected> class <class name>{ // <public/private/protected> class <class name> {
// //data fields, constructors, functions all inside. // // data fields, constructors, functions all inside.
// //functions are called as methods in Java. // // functions are called as methods in Java.
// } // }
class Bicycle { class Bicycle {
@ -342,7 +337,8 @@ class Bicycle {
} }
// This is a constructor that takes arguments // This is a constructor that takes arguments
public Bicycle(int startCadence, int startSpeed, int startGear, String name) { public Bicycle(int startCadence, int startSpeed, int startGear,
String name) {
this.gear = startGear; this.gear = startGear;
this.cadence = startCadence; this.cadence = startCadence;
this.speed = startSpeed; this.speed = startSpeed;
@ -388,10 +384,8 @@ class Bicycle {
//Method to display the attribute values of this Object. //Method to display the attribute values of this Object.
@Override @Override
public String toString() { public String toString() {
return "gear: " + gear + return "gear: " + gear + " cadence: " + cadence + " speed: " + speed +
" cadence: " + cadence + " name: " + name;
" speed: " + speed +
" name: " + name;
} }
} // end class Bicycle } // end class Bicycle
@ -405,26 +399,26 @@ class PennyFarthing extends Bicycle {
super(startCadence, startSpeed, 0, "PennyFarthing"); super(startCadence, startSpeed, 0, "PennyFarthing");
} }
// You should mark a method you're overriding with an @annotation // You should mark a method you're overriding with an @annotation.
// To learn more about what annotations are and their purpose // To learn more about what annotations are and their purpose check this
// check this out: http://docs.oracle.com/javase/tutorial/java/annotations/ // out: http://docs.oracle.com/javase/tutorial/java/annotations/
@Override @Override
public void setGear(int gear) { public void setGear(int gear) {
gear = 0; gear = 0;
} }
} }
//Interfaces // Interfaces
//Interface declaration syntax // Interface declaration syntax
//<access-level> interface <interface-name> extends <super-interfaces> { // <access-level> interface <interface-name> extends <super-interfaces> {
// //Constants // // Constants
// //Method declarations // // Method declarations
//} // }
//Example - Food: // Example - Food:
public interface Edible { public interface Edible {
public void eat(); //Any class that implements this interface, must implement this method public void eat(); // Any class that implements this interface, must
// implement this method.
} }
public interface Digestible { public interface Digestible {
@ -432,33 +426,31 @@ public interface Digestible {
} }
//We can now create a class that implements both of these interfaces // We can now create a class that implements both of these interfaces.
public class Fruit implements Edible, Digestible { public class Fruit implements Edible, Digestible {
@Override @Override
public void eat() { public void eat() {
//... // ...
} }
@Override @Override
public void digest() { public void digest() {
//... // ...
} }
} }
//In java, you can extend only one class, but you can implement many interfaces. // In Java, you can extend only one class, but you can implement many
//For example: // interfaces. For example:
public class ExampleClass extends ExampleClassParent implements InterfaceOne, InterfaceTwo { public class ExampleClass extends ExampleClassParent implements InterfaceOne,
InterfaceTwo {
@Override @Override
public void InterfaceOneMethod() { public void InterfaceOneMethod() {
} }
@Override @Override
public void InterfaceTwoMethod() { public void InterfaceTwoMethod() {
} }
} }
``` ```
## Further Reading ## Further Reading
@ -500,5 +492,3 @@ The links provided here below are just to get an understanding of the topic, fee
* [Objects First with Java](http://www.amazon.com/Objects-First-Java-Practical-Introduction/dp/0132492660) * [Objects First with Java](http://www.amazon.com/Objects-First-Java-Practical-Introduction/dp/0132492660)
* [Java The Complete Reference](http://www.amazon.com/gp/product/0071606300) * [Java The Complete Reference](http://www.amazon.com/gp/product/0071606300)

View File

@ -10,7 +10,7 @@ As JSON is an extremely simple data-interchange format, this is most likely goin
to be the simplest Learn X in Y Minutes ever. to be the simplest Learn X in Y Minutes ever.
JSON in its purest form has no actual comments, but most parsers will accept JSON in its purest form has no actual comments, but most parsers will accept
C-style (//, /\* \*/) comments. For the purposes of this, however, everything is C-style (`//`, `/* */`) comments. For the purposes of this, however, everything is
going to be 100% valid JSON. Luckily, it kind of speaks for itself. going to be 100% valid JSON. Luckily, it kind of speaks for itself.
```json ```json

View File

@ -8,7 +8,7 @@ filename: learnjulia.jl
Julia is a new homoiconic functional language focused on technical computing. Julia is a new homoiconic functional language focused on technical computing.
While having the full power of homoiconic macros, first-class functions, and low-level control, Julia is as easy to learn and use as Python. While having the full power of homoiconic macros, first-class functions, and low-level control, Julia is as easy to learn and use as Python.
This is based on the current development version of Julia, as of October 18th, 2013. This is based on Julia 0.3.
```ruby ```ruby
@ -91,7 +91,7 @@ false
# $ can be used for string interpolation: # $ can be used for string interpolation:
"2 + 2 = $(2 + 2)" # => "2 + 2 = 4" "2 + 2 = $(2 + 2)" # => "2 + 2 = 4"
# You can put any Julia expression inside the parenthesis. # You can put any Julia expression inside the parentheses.
# Another way to format strings is the printf macro. # Another way to format strings is the printf macro.
@printf "%d is less than %f" 4.5 5.3 # 5 is less than 5.300000 @printf "%d is less than %f" 4.5 5.3 # 5 is less than 5.300000
@ -190,7 +190,7 @@ end
# inside the julia folder to find these files. # inside the julia folder to find these files.
# You can initialize arrays from ranges # You can initialize arrays from ranges
a = [1:5] # => 5-element Int64 Array: [1,2,3,4,5] a = [1:5;] # => 5-element Int64 Array: [1,2,3,4,5]
# You can look at ranges with slice syntax. # You can look at ranges with slice syntax.
a[1:3] # => [1, 2, 3] a[1:3] # => [1, 2, 3]
@ -264,7 +264,7 @@ in(("two", 3), filled_dict) # => false
haskey(filled_dict, "one") # => true haskey(filled_dict, "one") # => true
haskey(filled_dict, 1) # => false haskey(filled_dict, 1) # => false
# Trying to look up a non-existant key will raise an error # Trying to look up a non-existent key will raise an error
try try
filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489 filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489
catch e catch e

View File

@ -155,7 +155,7 @@ var anotherArray = ["Default index", "starts at", "0"]
# More data structures are available, including tables, sets, lists, queues, # More data structures are available, including tables, sets, lists, queues,
# and crit bit trees. # and crit bit trees.
# http://nimrod-lang.org/lib.html#collections-and-algorithms # http://nim-lang.org/docs/lib.html#collections-and-algorithms
# #
# IO and Control Flow # IO and Control Flow
@ -174,7 +174,7 @@ else:
# `while`, `if`, `continue`, `break` # `while`, `if`, `continue`, `break`
import strutils as str # http://nimrod-lang.org/strutils.html import strutils as str # http://nim-lang.org/docs/strutils.html
echo "I'm thinking of a number between 41 and 43. Guess which!" echo "I'm thinking of a number between 41 and 43. Guess which!"
let number: int = 42 let number: int = 42
var var
@ -263,11 +263,11 @@ performance, and compile-time features.
## Further Reading ## Further Reading
* [Home Page](http://nimrod-lang.org) * [Home Page](http://nim-lang.org)
* [Download](http://nimrod-lang.org/download.html) * [Download](http://nim-lang.org/download.html)
* [Community](http://nimrod-lang.org/community.html) * [Community](http://nim-lang.org/community.html)
* [FAQ](http://nimrod-lang.org/question.html) * [FAQ](http://nim-lang.org/question.html)
* [Documentation](http://nimrod-lang.org/documentation.html) * [Documentation](http://nim-lang.org/documentation.html)
* [Manual](http://nimrod-lang.org/manual.html) * [Manual](http://nim-lang.org/docs/manual.html)
* [Standard Library](http://nimrod-lang.org/lib.html) * [Standard Library](http://nim-lang.org/docs/lib.html)
* [Rosetta Code](http://rosettacode.org/wiki/Category:Nimrod) * [Rosetta Code](http://rosettacode.org/wiki/Category:Nim)

View File

@ -47,9 +47,9 @@ my %fruit_color = ("apple", "red", "banana", "yellow");
# You can use whitespace and the "=>" operator to lay them out more nicely: # You can use whitespace and the "=>" operator to lay them out more nicely:
my %fruit_color = ( my %fruit_color = (
apple => "red", apple => "red",
banana => "yellow", banana => "yellow",
); );
# Scalars, arrays and hashes are documented more fully in perldata. # Scalars, arrays and hashes are documented more fully in perldata.
# (perldoc perldata). # (perldoc perldata).
@ -60,17 +60,17 @@ my %fruit_color = (
# Perl has most of the usual conditional and looping constructs. # Perl has most of the usual conditional and looping constructs.
if ( $var ) { if ($var) {
... ...
} elsif ( $var eq 'bar' ) { } elsif ($var eq 'bar') {
... ...
} else { } else {
... ...
} }
unless ( condition ) { unless (condition) {
... ...
} }
# This is provided as a more readable version of "if (!condition)" # This is provided as a more readable version of "if (!condition)"
# the Perlish post-condition way # the Perlish post-condition way
@ -78,19 +78,29 @@ print "Yow!" if $zippy;
print "We have no bananas" unless $bananas; print "We have no bananas" unless $bananas;
# while # while
while ( condition ) { while (condition) {
... ...
} }
# for and foreach # for loops and iteration
for ($i = 0; $i <= $max; $i++) { for (my $i = 0; $i < $max; $i++) {
... print "index is $i";
} }
foreach (@array) { for (my $i = 0; $i < @elements; $i++) {
print "This element is $_\n"; print "Current element is " . $elements[$i];
} }
for my $element (@elements) {
print $element;
}
# implicitly
for (@elements) {
print;
}
#### Regular expressions #### Regular expressions
@ -129,9 +139,11 @@ my @lines = <$in>;
# Writing subroutines is easy: # Writing subroutines is easy:
sub logger { sub logger {
my $logmessage = shift; my $logmessage = shift;
open my $logfile, ">>", "my.log" or die "Could not open my.log: $!";
print $logfile $logmessage; open my $logfile, ">>", "my.log" or die "Could not open my.log: $!";
print $logfile $logmessage;
} }
# Now we can use the subroutine just as any other built-in function: # Now we can use the subroutine just as any other built-in function:

View File

@ -213,7 +213,7 @@ say $x; #=> 52
# - `if` # - `if`
# Before talking about `if`, we need to know which values are "Truthy" # Before talking about `if`, we need to know which values are "Truthy"
# (represent True), and which are "Falsey" (or "Falsy") -- represent False. # (represent True), and which are "Falsey" (or "Falsy") -- represent False.
# Only these values are Falsey: (), 0, "0", "", Nil, A type (like `Str` or `Int`), # Only these values are Falsey: (), 0, "", Nil, A type (like `Str` or `Int`),
# and of course False itself. # and of course False itself.
# Every other value is Truthy. # Every other value is Truthy.
if True { if True {

View File

@ -60,7 +60,7 @@ $float = 1.2e3;
$float = 7E-10; $float = 7E-10;
// Delete variable // Delete variable
unset($int1) unset($int1);
// Arithmetic // Arithmetic
$sum = 1 + 1; // 2 $sum = 1 + 1; // 2

View File

@ -0,0 +1,637 @@
---
name: python
category: language
language: python
filename: learnpython-pl.py
contributors:
- ["Louie Dinh", "http://ldinh.ca"]
- ["Amin Bandali", "http://aminbandali.com"]
- ["Andre Polykanine", "https://github.com/Oire"]
translators:
- ["Dominik Krzemiński", "https://github.com/dokato"]
lang: pl-pl
---
Python został opracowany przez Guido Van Rossuma na początku lat 90-tych.
Obecnie jest jednym z najbardziej popularnych języków programowania.
Zakochałem się w Pythonie dzięki porządkowi, jaki utrzymywany jest w kodzie.
To po prostu wykonywalny pseudokod.
Zapraszam do kontaktu. Złapiecie nas na:
- kontakt polski: raymon92 [at] [google's email service]
- kontakt angielski: [@louiedinh](http://twitter.com/louiedinh) lub louiedinh [at] [google's email service]
Uwaga: Ten artykuł odnosi się do wersji Pythona 2.7, ale powinien
działać w wersjach 2.x. Dla wersji 3.x znajdziesz odpowiedni artykuł na stronie głównej.
```python
# -*- coding: utf-8 -*-
# Pojedyncze komentarze oznaczamy takim symbolem.
""" Wielolinijkowe napisy zapisywane są przy użyciu
trzech znaków cudzysłowiu i często
wykorzystywane są jako komentarze.
"""
####################################################
## 1. Podstawowe typy danych i operatory
####################################################
# Liczby to liczby
3 # => 3
# Matematyka jest intuicyjna
1 + 1 # => 2
8 - 1 # => 7
10 * 2 # => 20
35 / 5 # => 7
# Dzielenie może być kłopotliwe. Poniższe to dzielenie
# całkowitoliczbowe(int) i wynik jest automatycznie zaokrąglany.
5 / 2 # => 2
# Aby to naprawić musimy powiedzieć nieco o liczbach zmiennoprzecinkowych.
2.0 # To liczba zmiennoprzecinkowa, tzw. float
11.0 / 4.0 # => 2.75 ahhh...znacznie lepiej
# Wynik dzielenia całkowitoliczbowego jest obcinany dla liczb
# dodatnich i ujemnych.
5 // 3 # => 1
5.0 // 3.0 # => 1.0 # działa też na floatach
-5 // 3 # => -2
-5.0 // 3.0 # => -2.0
# Operator modulo - wyznaczanie reszty z dzielenia
7 % 3 # => 1
# Potęgowanie (x do potęgi ytej)
2**4 # => 16
# Wymuszanie pierwszeństwa w nawiasach
(1 + 3) * 2 # => 8
# Operacje logiczne
# Zauważ, że przy "and" i "or" trzeba zwracać uwagę na rozmiar liter
True and False #=> False # Fałsz
False or True #=> True # Prawda
# Zauważ, że operatorów logicznych można używać z intami
0 and 2 #=> 0
-5 or 0 #=> -5
0 == False #=> True
2 == True #=> False
k1 == True #=> True
# aby zanegować użyj "not"
not True # => False
not False # => True
# Równość ==
1 == 1 # => True
2 == 1 # => False
# Nierówność !=
1 != 1 # => False
2 != 1 # => True
# Więcej porównań
1 < 10 # => True
1 > 10 # => False
2 <= 2 # => True
2 >= 2 # => True
# Porównania można układać w łańcuch!
1 < 2 < 3 # => True
2 < 3 < 2 # => False
# Napisy (typ string) tworzone są przy użyciu cudzysłowów " lub '
"Jestem napisem."
'Ja też jestem napisem.'
# Napisy można dodawać!
"Witaj " + "świecie!" # => "Witaj świecie!"
# ... a nawet mnożone
"Hej" * 3 # => "HejHejHej"
# Napis może być traktowany jako lista znaków
"To napis"[0] # => 'T'
# % może być używane do formatowania napisów:
"%s są %s" % ("napisy", "fajne")
# Jednak nowszym sposobem formatowania jest metoda "format".
# Ta metoda jest obecnie polecana:
"{0} są {1}".format("napisy", "fajne")
# Jeśli nie chce ci się liczyć użyj słów kluczowych.
"{imie} chce zjeść {jadlo}".format(imie="Bob", jasno="lasagne")
# None jest obiektem
None # => None
# Nie używaj "==" w celu porównania obiektów z None
# Zamiast tego użyj "is"
"etc" is None # => False
None is None # => True
# Operator 'is' testuje identyczność obiektów. To nie jest zbyt
# pożyteczne, gdy działamy tylko na prostych wartościach,
# ale przydaje się, gdy mamy do czynienia z obiektami.
# None, 0, i pusty napis "" są odpowiednikami logicznego False.
# Wszystkie inne wartości są True
bool(0) # => False
bool("") # => False
####################################################
## 2. Zmienne i zbiory danych
####################################################
# Python ma wyrażenie wypisujące "print" we wszystkich wersjach 2.x, ale
# zostało usunięte z wersji 3.
print "Jestem Python. Miło poznać!"
# Python ma też funkcję "print" dostępną w wersjach 2.7 and 3...
# ale w 2.7 musisz dodać import (odkomentuj):
# from __future__ import print_function
print("Ja też jestem Python! ")
# Nie trzeba deklarować zmiennych przed przypisaniem.
jakas_zmienna = 5 # Konwencja mówi: używaj małych znaków i podłogi _
jakas_zmienna # => 5
# Próba dostępu do niezadeklarowanej zmiennej da błąd.
# Przejdź do sekcji Obsługa wyjątków po więcej...
inna_zmienna # Wyrzuca nazwę błędu
# "if" może być użyte jako wyrażenie
"huraaa!" if 3 > 2 else 2 # => "huraaa!"
# Listy:
li = []
# Możesz zacząć od wypełnionej listy
inna_li = [4, 5, 6]
# Dodaj na koniec używając "append"
li.append(1) # li to teraz [1]
li.append(2) # li to teraz [1, 2]
li.append(4) # li to teraz [1, 2, 4]
li.append(3) # li to teraz [1, 2, 4, 3]
# Usuwanie z konca da "pop"
li.pop() # => 3 a li stanie się [1, 2, 4]
# Dodajmy ponownie
li.append(3) # li to znowu [1, 2, 4, 3].
# Dostęp do list jak do każdej tablicy
li[0] # => 1
# Użyj = aby nadpisać wcześniej wypełnione miejsca w liście
li[0] = 42
li[0] # => 42
li[0] = 1 # Uwaga: ustawiamy starą wartość
# Tak podglądamy ostatni element
li[-1] # => 3
# Jeżeli wyjdziesz poza zakres...
li[4] # ... zobaczysz IndexError
# Możesz tworzyć wyniki.
li[1:3] # => [2, 4]
# Bez początku
li[2:] # => [4, 3]
# Omijamy koniec
li[:3] # => [1, 2, 4]
# Wybierz co drugi
li[::2] # =>[1, 4]
# Odwróć listę
li[::-1] # => [3, 4, 2, 1]
# Użyj kombinacji powyższych aby tworzyć bardziej skomplikowane wycinki
# li[poczatek:koniec:krok]
# Usuń element używając "del"
del li[2] # li to teraz [1, 2, 3]
# Listy można dodawać
li + inna_li # => [1, 2, 3, 4, 5, 6]
# Uwaga: wartości poszczególnych list się nie zmieniają.
# Do łączenia list użyj "extend()"
li.extend(other_li) # li to teraz [1, 2, 3, 4, 5, 6]
# Sprawdź czy jest w liście używając "in"
1 in li # => True
# "len()" pokazuje długość listy
len(li) # => 6
# Krotki (tuple) są jak listy, ale nie można ich modyfikować.
tup = (1, 2, 3)
tup[0] # => 1
tup[0] = 3 # wyrzuci TypeError
# Ale wielu akcji dla list możesz używać przy krotkach
len(tup) # => 3
tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
tup[:2] # => (1, 2)
2 in tup # => True
# Można rozpakować krotki i listy do poszczególych zmiennych
a, b, c = (1, 2, 3) # a to teraz 1, b jest 2, a c to 3
# Jeżeli zapomnisz nawiasów automatycznie tworzone są krotki
d, e, f = 4, 5, 6
# Popatrz jak prosto zamienić wartości
e, d = d, e # d to teraz 5 a e to 4
# Słowniki są również pożyteczne
pusty_slownik = {}
# Tu tworzymy wypełniony:
pelen_slownik = {"raz": 1, "dwa": 2, "trzy": 3}
# Podglądany wartość
pelen_slownik["one"] # => 1
# Wypisz wszystkie klucze używając "keys()"
pelen_slownik.keys() # => ["trzy", "dwa", "raz"]
# Uwaga: słowniki nie gwarantują kolejności występowania kluczy.
# A teraz wszystkie wartości "values()"
pelen_slownik.values() # => [3, 2, 1]
# Uwaga: to samo dotyczy wartości.
# Sprawdzanie czy występuje to "in"
"raz" in pelen_slownik # => True
1 in pelen_slownik # => False
# Próba dobrania się do nieistniejącego klucza da KeyError
pelen_slownik["cztery"] # KeyError
# Użyj "get()" method aby uniknąć KeyError
pelen_slownik.get("raz") # => 1
pelen_slownik.get("cztery") # => None
# Metoda get zwraca domyślną wartość gdy brakuje klucza
pelen_slownik.get("one", 4) # => 1
pelen_slownik.get("cztery", 4) # => 4
# zauważ, że pelen_slownik.get("cztery") jest wciąż => None
# (get nie ustawia wartości słownika)
# przypisz wartość do klucza podobnie jak w listach
pelen_slownik["cztery"] = 4 # teraz: pelen_slownik["cztery"] => 4
# "setdefault()" wstawia do słownika tylko jeśli nie było klucza
pelen_slownik.setdefault("piec", 5) # pelen_slownik["piec"] daje 5
pelen_slownik.setdefault("piec", 6) # pelen_slownik["piec"] to wciąż 5
# Teraz zbiory (set) ... cóż zbiory (to po prostu listy ale bez potórzeń)
pusty_zbior = set()
# Inicjalizujemy "set()" pewnymi wartościami
jakis_zbior = set([1, 2, 2, 3, 4]) # jakis_zbior to teraz set([1, 2, 3, 4])
# kolejność nie jest gwarantowana, nawet gdy wydaje się posortowane
inny_zbior = set([4, 3, 2, 2, 1]) # inny_zbior to set([1, 2, 3, 4])
# Od Pythona 2.7 nawiasy klamrowe {} mogą być użyte do deklarowania zbioru
pelen_zbior = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
# Dodaj więcej elementów przez "add()"
pelen_zbior.add(5) # pelen_zbior is now {1, 2, 3, 4, 5}
# Znajdź przecięcie zbiorów używając &
inny_zbior = {3, 4, 5, 6}
pelen_zbior & other_set # => {3, 4, 5}
# Suma zbiorów |
pelen_zbior | other_set # => {1, 2, 3, 4, 5, 6}
# Różnicę zbiorów da znak -
{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
# Sprawdzanie obecności w zbiorze: "in".
2 in pelen_zbior # => True
10 in pelen_zbior # => False
####################################################
## 3. Kontrola przepływu
####################################################
# Tworzymy zmienną some_var
some_var = 5
# Tutaj widzisz wyrażenie warunkowe "if". Wcięcia są ważne Pythonie!
# wypisze "some_var jest mniejsza niż 10"
if some_var > 10:
print("some_var jest wieksza niż 10")
elif some_var < 10: # This elif clause is optional.
print("some_var jest mniejsza niż 10")
else: # This is optional too.
print("some_var jest równa 10")
"""
Pętla for iteruje po elementach listy wypisując:
pies to ssak
kot to ssak
mysz to ssak
"""
for zwierze in ["pies", "kot", "mysz"]:
# Możesz użyć % aby stworzyć sformatowane napisy
print("%s to ssak" % zwierze)
"""
"range(liczba)" zwraca listę liczb
od zera do danej liczby:
0
1
2
3
"""
for i in range(4):
print(i)
"""
While to pętla która jest wykonywana dopóki spełniony jest warunek:
0
1
2
3
"""
x = 0
while x < 4:
print(x)
x += 1 # Skrót od x = x + 1
# Wyjątki wyłapujemy używając try, except
# Działa w Pythonie 2.6 i wyższych:
try:
# Użyj "raise" aby wyrzucić wyjąte
raise IndexError("To błąd indeksu")
except IndexError as e:
pass # Pass to brak reakcji na błąd. Zazwyczaj nanosisz tu poprawki.
except (TypeError, NameError):
pass # kilka wyjątków może być przechwyce razem.
else: # Opcjonalna część bloku try/except. Musi wystąpić na końcu
print "Wszystko ok!" # Zadziała tylko, gdy program nie napotka wyjatku.
####################################################
## 4. Funkcjie
####################################################
# Użyj "def" aby stworzyć nową funkcję
def dodaj(x, y):
print("x to %s a y to %s" % (x, y))
return x + y # słówko kluczowe return zwraca wynik działania
# Tak wywołuje się funkcję z parametrami (args):
dodaj(5, 6) # => wypisze "x to 5 a y to 6" i zwróci 11
# Innym sposobem jest wywołanie z parametrami nazwanymi.
dodaj(y=6, x=5) # tutaj kolejność podania nie ma znaczenia.
# Można też stworzyć funkcję, które przyjmują różną ilość parametrów
# nienazwanych args, co będzie interpretowane jako krotka jeśli nie użyjesz *
def varargs(*args):
return args
varargs(1, 2, 3) # => (1, 2, 3)
# Można też stworzyć funkcję, które przyjmują różną ilość parametrów
# nazwanych kwargs, które będa interpretowane jako słownik jeśli nie dasz **
def keyword_args(**kwargs):
return kwargs
# Wywołajmy to i sprawdźmy co się dzieje
keyword_args(wielka="stopa", loch="ness") # => {"wielka": "stopa", "loch": "ness"}
# Możesz też to pomieszać
def all_the_args(*args, **kwargs):
print(args)
print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) wyrzuci:
(1, 2)
{"a": 3, "b": 4}
"""
# Użyj * aby rozwinąć parametry z krotki args
# i użyj ** aby rozwinąć parametry nazwane ze słownika kwargs.
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
all_the_args(*args) # odpowiednik foo(1, 2, 3, 4)
all_the_args(**kwargs) # odpowiednik foo(a=3, b=4)
all_the_args(*args, **kwargs) # odpowiednik foo(1, 2, 3, 4, a=3, b=4)
# Możesz podać parametry args i kwargs do funkcji równocześnie
# przez rozwinięcie odpowiednio * i **
def pass_all_the_args(*args, **kwargs):
all_the_args(*args, **kwargs)
print varargs(*args)
print keyword_args(**kwargs)
# Zakres widoczności
x = 5
def setX(num):
# Lokalna zmienna x nie jest tym samym co zmienna x
x = num # => 43
print x # => 43
def setGlobalX(num):
global x
print x # => 5
x = num # globalna zmienna to teraz 6
print x # => 6
setX(43)
setGlobalX(6)
# Można tworzyć funkcje wewnętrzne i zwrócić je jako wynik
def rob_dodawacz(x):
def dodawacz(y):
return x + y
return dodawacz
dodaj_10 = rob_dodawacz(10)
dodaj_10(3) # => 13
# Są również funkcje nienazwane "lambda"
(lambda x: x > 2)(3) # => True
# Są także wbudowane funkcje wysokiego poziomu
map(add_10, [1, 2, 3]) # => [11, 12, 13]
filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
# Można używać wyrażeń listowych do mapowania (map) i filtrowania (filter)
[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
####################################################
## 5. Klasy
####################################################
# Wszystkie klasy są podklasą object
class Czlowiek(object):
# Atrybut klasy. Występuje we wszystkich instancjach klasy.
gatunek = "H. sapiens"
# Podstawowa inicjalizacja - wywoływana podczas tworzenia instacji.
# Zauważ, że podwójne podkreślenia przed i za nazwą oznaczają
# obietky lub atrybuty, który żyją tylko w kontrolowanej przez
# użytkownika przestrzeni nazw. Nie używaj ich we własnych metodach.
def __init__(self, nazwa):
# przypisz parametr "nazwa" do atrybutu instancji
self.nazwa = nazwa
# Metoda instancji. Wszystkie metody biorą "self" jako pierwszy argument
def mow(self, wiadomosc):
return "%s: %s" % (self.nazwa, wiadomosc)
# Metoda klasowa współdzielona przez instancje.
# Ma wywołującą klasę jako pierwszy argument.
@classmethod
def daj_gatunek(cls):
return cls.gatunek
# Metoda statyczna jest wywoływana bez argumentów klasy czy instancji.
@staticmethod
def grunt():
return "*grunt*"
# Instancja klasy
i = Czlowiek(name="Ian")
print(i.mow("cześć")) # wypisze "Ian: cześć"
j = Czlowiek("Joel")
print(j.mow("cześć")) # wypisze "Joel: cześć"
# Wywołujemy naszą metodę klasową
i.daj_gatunek() # => "H. sapiens"
# Zmieniamy wspólny parametr
Czlowiek.gatunek = "H. neanderthalensis"
i.daj_gatunek() # => "H. neanderthalensis"
j.daj_gatunek() # => "H. neanderthalensis"
# Wywołanie metody statycznej
Czlowiek.grunt() # => "*grunt*"
####################################################
## 6. Moduły
####################################################
# Tak importuje się moduły:
import math
print(math.sqrt(16)) # => 4
# Można podać konkretne funkcje, np. ceil, floor z modułu math
from math import ceil, floor
print(ceil(3.7)) # => 4.0
print(floor(3.7)) # => 3.0
# Można zaimportować wszystkie funkcje z danego modułu.
# Ostrzeżenie: nie jest to polecane.
from math import *
# Można skracać nazwy modułów.
import math as m
math.sqrt(16) == m.sqrt(16) # => True
# sprawdźmy czy funkcje są równoważne
from math import sqrt
math.sqrt == m.sqrt == sqrt # => True
# Moduły pythona to zwykłe skrypty napisane w tym języku. Możesz
# pisać własne i importować je. Nazwa modułu to nazwa pliku.
# W ten sposób sprawdzisz jakie funkcje wchodzą w skład modułu.
import math
dir(math)
####################################################
## 7. Zaawansowane
####################################################
# Generatory pomagają tworzyć tzw. "leniwy kod"
def podwojne_liczby(iterowalne):
for i in iterowalne:
yield i + i
# Generatory tworzą wartości w locie.
# W przeciwienstwie do wygenerowania wartości raz i ich zachowania,
# powstają one na bieżąco, w wyniku iteracji. To oznacza, że wartości
# większe niż 15 nie będą przetworzone w funkcji "podwojne_liczby".
# Zauważ, że xrange to generator, który wykonuje tę samą operację co range.
# Stworzenie listy od 1 do 900000000 zajęłoby sporo czasu i pamięci,
# a xrange tworzy obiekt generatora zamiast tworzyć całą listę jak range.
# Użyto podkreślinika, aby odróżnić nazwę zmiennej od słówka kluczowego
# Pythona.
xrange_ = xrange(1, 900000000)
# poniższa pętla będzie podwajać liczby aż do 30
for i in podwojne_liczby(xrange_):
print(i)
if i >= 30:
break
# Dekoratory
# w tym przykładzie "beg" jest nakładką na "say"
# Beg wywołuje say. Jeśli say_please jest prawdziwe wtedy wzracana wartość
# zostanie zmieniona
from functools import wraps
def beg(target_function):
@wraps(target_function)
def wrapper(*args, **kwargs):
msg, say_please = target_function(*args, **kwargs)
if say_please:
return "{} {}".format(msg, "Proszę! Jestem spłukany :(")
return msg
return wrapper
@beg
def say(say_please=False):
msg = "Kupisz mi piwo?"
return msg, say_please
print(say()) # Kupisz mi piwo?
print(say(say_please=True)) # Kupisz mi piwo? Proszę! Jestem spłukany :(
```
## Gotowy na więcej?
### Polskie
* [Zanurkuj w Pythonie](http://pl.wikibooks.org/wiki/Zanurkuj_w_Pythonie)
* [LearnPythonPl](http://www.learnpython.org/pl/)
### Angielskie:
#### Darmowe źródła online
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
* [Dive Into Python](http://www.diveintopython.net/)
* [The Official Docs](http://docs.python.org/2.6/)
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
* [Python Module of the Week](http://pymotw.com/2/)
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
#### Inne
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)

View File

@ -9,7 +9,7 @@ translators:
lang: pt-br lang: pt-br
--- ---
Groovy - Uma linguagem dinâmica para a plataforma Java. [Leia mais aqui.](http://groovy.codehaus.org) Groovy - Uma linguagem dinâmica para a plataforma Java. [Leia mais aqui.](http://www.groovy-lang.org/)
```groovy ```groovy
@ -236,7 +236,7 @@ for ( e in map ) {
Sobrecarregamento de Operadores para uma lsita dos operadores comuns que Sobrecarregamento de Operadores para uma lsita dos operadores comuns que
Grooby suporta: Grooby suporta:
http://groovy.codehaus.org/Operator+Overloading http://www.groovy-lang.org/operators.html#Operator-Overloading
Operadores Groovy úteis Operadores Groovy úteis
*/ */
@ -255,7 +255,7 @@ def nomeUsuario = usuario?.nomeUsuario
Um closure, em Grooby, é como um "bloco de código" ou um ponteiro para método. Um closure, em Grooby, é como um "bloco de código" ou um ponteiro para método.
É um pedação de código que é definido e executado em um momento posterior. É um pedação de código que é definido e executado em um momento posterior.
Mais informação em: http://groovy.codehaus.org/Closures+-+Formal+Definition Mais informação em: http://www.groovy-lang.org/closures.html
*/ */
//Exemplo: //Exemplo:
def clos = { println "Hello World!" } def clos = { println "Hello World!" }
@ -413,11 +413,11 @@ assert soma(2,5) == 7
## Referências ## Referências
[Groovy documentation](http://groovy.codehaus.org/Documentation) [Groovy documentation](http://www.groovy-lang.org/documentation.html)
[Groovy web console](http://groovyconsole.appspot.com/) [Groovy web console](http://groovyconsole.appspot.com/)
Junte-se a um [grupo de usuários Groovy](http://groovy.codehaus.org/User+Groups) Junte-se a um [grupo de usuários Groovy](http://www.groovy-lang.org/usergroups.html)
## Livro ## Livro

View File

@ -191,14 +191,14 @@ li[2:] # => [4, 3]
li[:3] # => [1, 2, 4] li[:3] # => [1, 2, 4]
# Select every second entry # Select every second entry
li[::2] # =>[1, 4] li[::2] # =>[1, 4]
# Revert the list # Reverse a copy of the list
li[::-1] # => [3, 4, 2, 1] li[::-1] # => [3, 4, 2, 1]
# Use any combination of these to make advanced slices # Use any combination of these to make advanced slices
# li[start:end:step] # li[start:end:step]
# Remove arbitrary elements from a list with "del" # Remove arbitrary elements from a list with "del"
del li[2] # li is now [1, 2, 3] del li[2] # li is now [1, 2, 3]
r
# You can add lists # You can add lists
li + other_li # => [1, 2, 3, 4, 5, 6] li + other_li # => [1, 2, 3, 4, 5, 6]
# Note: values for li and for other_li are not modified. # Note: values for li and for other_li are not modified.

View File

@ -186,7 +186,7 @@ li[2:] # => [4, 3]
li[:3] # => [1, 2, 4] li[:3] # => [1, 2, 4]
# Select every second entry # Select every second entry
li[::2] # =>[1, 4] li[::2] # =>[1, 4]
# Revert the list # Return a reversed copy of the list
li[::-1] # => [3, 4, 2, 1] li[::-1] # => [3, 4, 2, 1]
# Use any combination of these to make advanced slices # Use any combination of these to make advanced slices
# li[start:end:step] # li[start:end:step]
@ -213,7 +213,7 @@ tup = (1, 2, 3)
tup[0] # => 1 tup[0] # => 1
tup[0] = 3 # Raises a TypeError tup[0] = 3 # Raises a TypeError
# You can do all those list thingies on tuples too # You can do most of the list operations on tuples too
len(tup) # => 3 len(tup) # => 3
tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6) tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
tup[:2] # => (1, 2) tup[:2] # => (1, 2)
@ -235,15 +235,15 @@ filled_dict = {"one": 1, "two": 2, "three": 3}
# Look up values with [] # Look up values with []
filled_dict["one"] # => 1 filled_dict["one"] # => 1
# Get all keys as a list with "keys()". # Get all keys as an iterable with "keys()". We need to wrap the call in list()
# We need to wrap the call in list() because we are getting back an iterable. We'll talk about those later. # to turn it into a list. We'll talk about those later. Note - Dictionary key
# Note - Dictionary key ordering is not guaranteed. # ordering is not guaranteed. Your results might not match this exactly.
# Your results might not match this exactly.
list(filled_dict.keys()) # => ["three", "two", "one"] list(filled_dict.keys()) # => ["three", "two", "one"]
# Get all values as a list with "values()". Once again we need to wrap it in list() to get it out of the iterable. # Get all values as an iterable with "values()". Once again we need to wrap it
# Note - Same as above regarding key ordering. # in list() to get it out of the iterable. Note - Same as above regarding key
# ordering.
list(filled_dict.values()) # => [3, 2, 1] list(filled_dict.values()) # => [3, 2, 1]
@ -328,7 +328,7 @@ for animal in ["dog", "cat", "mouse"]:
print("{} is a mammal".format(animal)) print("{} is a mammal".format(animal))
""" """
"range(number)" returns a list of numbers "range(number)" returns an iterable of numbers
from zero to the given number from zero to the given number
prints: prints:
0 0
@ -340,7 +340,7 @@ for i in range(4):
print(i) print(i)
""" """
"range(lower, upper)" returns a list of numbers "range(lower, upper)" returns an iterable of numbers
from the lower number to the upper number from the lower number to the upper number
prints: prints:
4 4

284
ru-ru/bash-ru.html.markdown Normal file
View File

@ -0,0 +1,284 @@
---
category: tool
tool: bash
contributors:
- ["Max Yankov", "https://github.com/golergka"]
- ["Darren Lin", "https://github.com/CogBear"]
- ["Alexandre Medeiros", "http://alemedeiros.sdf.org"]
- ["Denis Arh", "https://github.com/darh"]
- ["akirahirose", "https://twitter.com/akirahirose"]
- ["Anton Strömkvist", "http://lutic.org/"]
- ["Rahil Momin", "https://github.com/iamrahil"]
- ["Gregrory Kielian", "https://github.com/gskielian"]
- ["Etan Reisner", "https://github.com/deryni"]
translators:
- ["Andrey Samsonov", "https://github.com/kryzhovnik"]
- ["Andre Polykanine", "https://github.com/Oire"]
filename: LearnBash-ru.sh
lang: ru-ru
---
Bash - это командная оболочка unix (unix shell), которая распространялась как оболочка для операционной системы GNU и используется в качестве оболочки по умолчанию для Linux и Mac OS X.
Почти все нижеприведенные примеры могут быть частью shell-скриптов или исполнены напрямую в shell.
[Подробнее.](http://www.gnu.org/software/bash/manual/bashref.html)
```bash
#!/bin/bash
# Первая строка скрипта - это shebang, который сообщает системе, как исполнять
# этот скрипт: http://en.wikipedia.org/wiki/Shebang_(Unix)
# Как вы уже поняли, комментарии начинаются с #. Shebang - тоже комментарий.
# Простой пример hello world:
echo Hello world!
# Отдельные команды начинаются с новой строки или разделяются точкой с запятой:
echo 'Это первая строка'; echo 'Это вторая строка'
# Вот так объявляется переменная:
VARIABLE="Просто строка"
# но не так:
VARIABLE = "Просто строка"
# Bash решит, что VARIABLE - это команда, которую он должен исполнить,
# и выдаст ошибку, потому что не сможет найти ее.
# и не так:
VARIABLE= 'Просто строка'
# Тут Bash решит, что 'Просто строка' - это команда, которую он должен исполнить,
# и выдаст ошибку, потому что не сможет найти такой команды
# (здесь 'VARIABLE=' выглядит как присвоение значения переменной,
# но только в контексте исполнения команды 'Просто строка').
# Использование переменой:
echo $VARIABLE
echo "$VARIABLE"
echo '$VARIABLE'
# Когда вы используете переменную - присваиваете, экспортируете и т.д. -
# пишите её имя без $. А для получения значения переменной используйте $.
# Заметьте, что ' (одинарные кавычки) не раскрывают переменные в них.
# Подстановка строк в переменные
echo ${VARIABLE/Просто/A}
# Это выражение заменит первую встреченную подстроку "Просто" на "A"
# Взять подстроку из переменной
LENGTH=7
echo ${VARIABLE:0:LENGTH}
# Это выражение вернет только первые 7 символов переменной VARIABLE
# Значение по умолчанию
echo ${FOO:-"DefaultValueIfFOOIsMissingOrEmpty"}
# Это сработает при отсутствующем значении (FOO=) и пустой строке (FOO="");
# ноль (FOO=0) вернет 0.
# Заметьте, что в любом случае значение самой переменной FOO не изменится.
# Встроенные переменные:
# В bash есть полезные встроенные переменные, например
echo "Последнее возвращенное значение: $?"
echo "PID скрипта: $$"
echo "Количество аргументов: $#"
echo "Аргументы скрипта: $@"
echo "Аргументы скрипта, распределённые по отдельным переменным: $1 $2..."
# Чтение аргументов из устройста ввода:
echo "Как Вас зовут?"
read NAME # Обратите внимание, что нам не нужно определять новую переменную
echo Привет, $NAME!
# У нас есть обычная структура if:
# наберите 'man test' для получения подробной информации о форматах условия
if [ $NAME -ne $USER ]
then
echo "Имя не совпадает с именем пользователя"
else
echo "Имя совпадает с именем пользователя"
fi
# Также есть условное исполнение
echo "Исполнится всегда" || echo "Исполнится, если первая команда завершится ошибкой"
echo "Исполнится всегда" && echo "Исполнится, если первая команда выполнится удачно"
# Можно использовать && и || в выражениях if, когда нужно несколько пар скобок:
if [ $NAME == "Steve" ] && [ $AGE -eq 15 ]
then
echo "Исполнится, если $NAME равно Steve И $AGE равно 15."
fi
if [ $NAME == "Daniya" ] || [ $NAME == "Zach" ]
then
echo "Исполнится, если $NAME равно Daniya ИЛИ Zach."
fi
# Выражения обозначаются таким форматом:
echo $(( 10 + 5 ))
# В отличие от других языков программирования, Bash - это командная оболочка,
# а значит, работает в контексте текущей директории.
# Вы можете просматривать файлы и директории в текущей директории командой ls:
ls
# У этой команды есть опции:
ls -l # Показать каждый файл и директорию на отдельной строке
# Результат предыдущей команды может быть направлен на вход следующей.
# Команда grep фильтрует ввод по шаблону.
# Так мы можем просмотреть только *.txt файлы в текущей директории:
ls -l | grep "\.txt"
# Вы можете перенаправить ввод и вывод команды (stdin, stdout и stderr).
# Следующая команда означает: читать из stdin, пока не встретится ^EOF$, и
# перезаписать hello.py следующим строками (до строки "EOF"):
cat > hello.py << EOF
#!/usr/bin/env python
from __future__ import print_function
import sys
print("#stdout", file=sys.stdout)
print("#stderr", file=sys.stderr)
for line in sys.stdin:
print(line, file=sys.stdout)
EOF
# Запуск hello.py с разными вариантами перенаправления потоков
# стандартных ввода, вывода и ошибок:
python hello.py < "input.in"
python hello.py > "output.out"
python hello.py 2> "error.err"
python hello.py > "output-and-error.log" 2>&1
python hello.py > /dev/null 2>&1
# Поток ошибок перезапишет файл, если этот файл существует,
# поэтому, если вы хотите дописывать файл, используйте ">>":
python hello.py >> "output.out" 2>> "error.err"
# Переписать output.txt, дописать error.err и сосчитать строки:
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
wc -l output.out error.err
# Запустить команду и вывести ее файловый дескриптор (смотрите: man fd)
echo <(echo "#helloworld")
# Перезаписать output.txt строкой "#helloworld":
cat > output.out <(echo "#helloworld")
echo "#helloworld" > output.out
echo "#helloworld" | cat > output.out
echo "#helloworld" | tee output.out >/dev/null
# Подчистить временные файлы с подробным выводом ('-i' - интерактивый режим)
rm -v output.out error.err output-and-error.log
# Команды могут быть подставлены в строку с помощью $( ):
# следующие команды выводят число файлов и директорий в текущей директории.
echo "Здесь $(ls | wc -l) элементов."
# То же самое можно сделать с использованием обратных кавычек,
# но они не могут быть вложенными, поэтому предпочтительно использовать $( ).
echo "Здесь `ls | wc -l` элементов."
# В Bash есть структура case, которая похожа на switch в Java и C++:
case "$VARIABLE" in
# Перечислите шаблоны для условий, которые хотите отловить
0) echo "Тут ноль.";;
1) echo "Тут один.";;
*) echo "Это не пустое значение.";;
esac
# Цикл for перебирает элементы переданные в аргументе:
# Содержимое $VARIABLE будет напечатано три раза.
for VARIABLE in {1..3}
do
echo "$VARIABLE"
done
# Или с использованием "традиционного" синтаксиса цикла for:
for ((a=1; a <= 3; a++))
do
echo $a
done
# Цикл for можно использовать для действий с файлами.
# Запустим команду 'cat' для файлов file1 и file2
for VARIABLE in file1 file2
do
cat "$VARIABLE"
done
# ... или выводом из команд
# Запустим cat для вывода из ls.
for OUTPUT in $(ls)
do
cat "$OUTPUT"
done
# Цикл while:
while [ true ]
do
echo "тело цикла здесь..."
break
done
# Вы можете определять функции
# Определение:
function foo ()
{
echo "Аргументы работают также, как аргументы скрипта: $@"
echo "и: $1 $2..."
echo "Это функция"
return 0
}
# или просто
bar ()
{
echo "Другой способ определить функцию!"
return 0
}
# Вызов функции
foo "Мое имя" $NAME
# Есть много полезных команд, которые нужно знать:
# напечатать последние 10 строк файла file.txt
tail -n 10 file.txt
# напечатать первые 10 строк файла file.txt
head -n 10 file.txt
# отсортировать строки file.txt
sort file.txt
# отобрать или наоборот пропустить повторяющиеся строки (с опцией -d отбирает)
uniq -d file.txt
# напечатать только первую колонку перед символом ','
cut -d ',' -f 1 file.txt
# заменить каждое 'okay' на 'great' в файле file.txt (regex поддерживается)
sed -i 's/okay/great/g' file.txt
# вывести в stdout все строки из file.txt, совпадающие с шаблоном regex;
# этот пример выводит строки, которые начинаются на "foo" и оканчиваются "bar"
grep "^foo.*bar$" file.txt
# передайте опцию -c чтобы вывести число строк, в которых совпал шаблон
grep -c "^foo.*bar$" file.txt
# чтобы искать по строке, а не шаблону regex, используйте fgrep (или grep -F)
fgrep "^foo.*bar$" file.txt
# Читайте встроенную документацию оболочки Bash командой 'help':
help
help help
help for
help return
help source
help .
# Читайте Bash man-документацию
apropos bash
man 1 bash
man bash
# Читайте документацию info (? для помощи)
apropos info | grep '^info.*('
man info
info info
info 5 info
# Читайте bash info документацию:
info bash
info bash 'Bash Features'
info bash 6
info --apropos bash
```

View File

@ -79,10 +79,14 @@ true && false #=> false
true || false #=> true true || false #=> true
!true #=> false !true #=> false
# Alternate spellings of logical operators # There are alternate versions of the logical operators with much lower
true and false #=> false # precedence. These are meant to be used as flow-control constructs to chain
true or false #=> true # statements together until one of them returns true or false.
not true #=> false
# `do_something_else` only called if `do_something` succeeds.
do_something() and do_something_else()
# `log_error` only called if `do_something` fails.
do_something() or log_error()
# Strings are objects # Strings are objects

View File

@ -5,15 +5,22 @@ contributors:
filename: learnrust.rs filename: learnrust.rs
--- ---
Rust is an in-development programming language developed by Mozilla Research. Rust is a programming language developed by Mozilla Research.
It is relatively unique among systems languages in that it can assert memory Rust combines low-level control over performance with high-level convenience and
safety *at compile time* without resorting to garbage collection. Rusts first safety guarantees.
release, 0.1, occurred in January 2012, and development moves so quickly that at
the moment the use of stable releases is discouraged, and instead one should use It achieves these goals without requiring a garbage collector or runtime, making
nightly builds. On January 9 2015, Rust 1.0 Alpha was released, and the rate of it possible to use Rust libraries as a "drop-in replacement" for C.
changes to the Rust compiler that break existing code has dropped significantly
since. However, a complete guarantee of backward compatibility will not exist Rusts first release, 0.1, occurred in January 2012, and for 3 years development
until the final 1.0 release. moved so quickly that until recently the use of stable releases was discouraged
and instead the general advise was to use nightly builds.
On May 15th 2015, Rust 1.0 was released with a complete guarantee of backward
compatibility. Improvements to compile times and other aspects of the compiler are
currently available in the nightly builds. Rust has adopted a train-based release
model with regular releases every six weeks. Rust 1.1 beta was made available at
the same time of the release of Rust 1.0.
Although Rust is a relatively low-level language, Rust has some functional Although Rust is a relatively low-level language, Rust has some functional
concepts that are generally found in higher-level languages. This makes concepts that are generally found in higher-level languages. This makes
@ -77,7 +84,7 @@ fn main() {
// This is basically an immutable pointer to a string it doesnt // This is basically an immutable pointer to a string it doesnt
// actually contain the contents of a string, just a pointer to // actually contain the contents of a string, just a pointer to
// something that does (in this case, `s`) // something that does (in this case, `s`)
let s_slice: &str = &*s; let s_slice: &str = &s;
println!("{} {}", s, s_slice); // hello world hello world println!("{} {}", s, s_slice); // hello world hello world
@ -92,7 +99,7 @@ fn main() {
// A slice an immutable view into a vector or array // A slice an immutable view into a vector or array
// This is much like a string slice, but for vectors // This is much like a string slice, but for vectors
let slice: &[i32] = &*vector; let slice: &[i32] = &vector;
// Use `{:?}` to print something debug-style // Use `{:?}` to print something debug-style
println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]

View File

@ -3,13 +3,15 @@ language: "Standard ML"
contributors: contributors:
- ["Simon Shine", "http://shine.eu.org/"] - ["Simon Shine", "http://shine.eu.org/"]
- ["David Pedersen", "http://lonelyproton.com/"] - ["David Pedersen", "http://lonelyproton.com/"]
- ["James Baker", "http://www.jbaker.io/"]
- ["Leo Zovic", "http://langnostic.inaimathi.ca/"]
--- ---
Standard ML is a functional programming language with type inference and some Standard ML is a functional programming language with type inference and some
side-effects. Some of the hard parts of learning Standard ML are: Recursion, side-effects. Some of the hard parts of learning Standard ML are: Recursion,
pattern matching, type inference (guessing the right types but never allowing pattern matching, type inference (guessing the right types but never allowing
implicit type conversion). If you have an imperative background, not being able implicit type conversion). Standard ML is distinguished from Haskell by including
to update variables can feel severely inhibiting. references, allowing variables to be updated.
```ocaml ```ocaml
(* Comments in Standard ML begin with (* and end with *). Comments can be (* Comments in Standard ML begin with (* and end with *). Comments can be
@ -135,9 +137,29 @@ val mixup = [ ("Alice", 39),
val good_bad_stuff = val good_bad_stuff =
(["ice cream", "hot dogs", "chocolate"], (["ice cream", "hot dogs", "chocolate"],
["liver", "paying the rent" ]) (* string list * string list *) ["liver", "paying the rent" ]) (* : string list * string list *)
(* Records are tuples with named slots *)
val rgb = { r=0.23, g=0.56, b=0.91 } (* : {b:real, g:real, r:real} *)
(* You don't need to declare their slots ahead of time. Records with
different slot names are considered different types, even if their
slot value types match up. For instance... *)
val Hsl = { H=310.3, s=0.51, l=0.23 } (* : {H:real, l:real, s:real} *)
val Hsv = { H=310.3, s=0.51, v=0.23 } (* : {H:real, s:real, v:real} *)
(* ...trying to evaluate `Hsv = Hsl` or `rgb = Hsl` would give a type
error. While they're all three-slot records composed only of `real`s,
they each have different names for at least some slots. *)
(* You can use hash notation to get values out of tuples. *)
val H = #H Hsv (* : real *)
val s = #s Hsl (* : real *)
(* Functions! *) (* Functions! *)
fun add_them (a, b) = a + b (* A simple function that adds two numbers *) fun add_them (a, b) = a + b (* A simple function that adds two numbers *)
val test_it = add_them (3, 4) (* gives 7 *) val test_it = add_them (3, 4) (* gives 7 *)
@ -224,17 +246,26 @@ fun fibonacci 0 = 0 (* Base case *)
| fibonacci 1 = 1 (* Base case *) | fibonacci 1 = 1 (* Base case *)
| fibonacci n = fibonacci (n - 1) + fibonacci (n - 2) (* Recursive case *) | fibonacci n = fibonacci (n - 1) + fibonacci (n - 2) (* Recursive case *)
(* Pattern matching is also possible on composite types like tuples and lists. (* Pattern matching is also possible on composite types like tuples, lists and
Writing "fun solve2 (a, b, c) = ..." is in fact a pattern match on the one records. Writing "fun solve2 (a, b, c) = ..." is in fact a pattern match on
three-tuple solve2 takes as argument. Similarly, but less intuitively, you the one three-tuple solve2 takes as argument. Similarly, but less intuitively,
can match on a list consisting of elements in it (from the beginning of the you can match on a list consisting of elements in it (from the beginning of
list only). *) the list only). *)
fun first_elem (x::xs) = x fun first_elem (x::xs) = x
fun second_elem (x::y::xs) = y fun second_elem (x::y::xs) = y
fun evenly_positioned_elems (odd::even::xs) = even::evenly_positioned_elems xs fun evenly_positioned_elems (odd::even::xs) = even::evenly_positioned_elems xs
| evenly_positioned_elems [odd] = [] (* Base case: throw away *) | evenly_positioned_elems [odd] = [] (* Base case: throw away *)
| evenly_positioned_elems [] = [] (* Base case *) | evenly_positioned_elems [] = [] (* Base case *)
(* When matching on records, you must use their slot names, and you must bind
every slot in a record. The order of the slots doesn't matter though. *)
fun rgbToTup {r, g, b} = (r, g, b) (* fn : {b:'a, g:'b, r:'c} -> 'c * 'b * 'a *)
fun mixRgbToTup {g, b, r} = (r, g, b) (* fn : {b:'a, g:'b, r:'c} -> 'c * 'b * 'a *)
(* If called with {r=0.1, g=0.2, b=0.3}, either of the above functions
would return (0.1, 0.2, 0.3). But it would be a type error to call them
with {r=0.1, g=0.2, b=0.3, a=0.4} *)
(* Higher order functions: Functions can take other functions as arguments. (* Higher order functions: Functions can take other functions as arguments.
Functions are just other kinds of values, and functions don't need names Functions are just other kinds of values, and functions don't need names
@ -383,6 +414,25 @@ val test_poem = readPoem "roses.txt" (* gives [ "Roses are red,",
"Violets are blue.", "Violets are blue.",
"I have a gun.", "I have a gun.",
"Get in the van." ] *) "Get in the van." ] *)
(* We can create references to data which can be updated *)
val counter = ref 0 (* Produce a reference with the ref function *)
(* Assign to a reference with the assignment operator *)
fun set_five reference = reference := 5
(* Read a reference with the dereference operator *)
fun equals_five reference = !reference = 5
(* We can use while loops for when recursion is messy *)
fun decrement_to_zero r = if !r < 0
then r := 0
else while !r >= 0 do r := !r - 1
(* This returns the unit value (in practical terms, nothing, a 0-tuple) *)
(* To allow returning a value, we can use the semicolon to sequence evaluations *)
fun decrement_ret x y = (x := !x - 1; y)
``` ```
## Further learning ## Further learning

View File

@ -159,7 +159,7 @@ Module Module1
Console.Write(a.ToString() + " - " + b.ToString()) Console.Write(a.ToString() + " - " + b.ToString())
Console.WriteLine(" = " + e.ToString.PadLeft(3)) Console.WriteLine(" = " + e.ToString.PadLeft(3))
Console.Write(a.ToString() + " / " + b.ToString()) Console.Write(a.ToString() + " / " + b.ToString())
Console.WriteLine(" = " + e.ToString.PadLeft(3)) Console.WriteLine(" = " + f.ToString.PadLeft(3))
Console.ReadLine() Console.ReadLine()
End Sub End Sub
@ -189,7 +189,7 @@ Module Module1
Console.Write(a.ToString() + " - " + b.ToString()) Console.Write(a.ToString() + " - " + b.ToString())
Console.WriteLine(" = " + e.ToString.PadLeft(3)) Console.WriteLine(" = " + e.ToString.PadLeft(3))
Console.Write(a.ToString() + " / " + b.ToString()) Console.Write(a.ToString() + " / " + b.ToString())
Console.WriteLine(" = " + e.ToString.PadLeft(3)) Console.WriteLine(" = " + f.ToString.PadLeft(3))
Console.ReadLine() Console.ReadLine()
'Ask the question, does the user wish to continue? Unfortunately it 'Ask the question, does the user wish to continue? Unfortunately it
'is case sensitive. 'is case sensitive.

View File

@ -5,7 +5,14 @@ contributors:
- ["Max Yankov", "https://github.com/golergka"] - ["Max Yankov", "https://github.com/golergka"]
- ["Darren Lin", "https://github.com/CogBear"] - ["Darren Lin", "https://github.com/CogBear"]
- ["Alexandre Medeiros", "http://alemedeiros.sdf.org"] - ["Alexandre Medeiros", "http://alemedeiros.sdf.org"]
- ["Denis Arh", "https://github.com/darh"]
- ["akirahirose", "https://twitter.com/akirahirose"]
- ["Anton Strömkvist", "http://lutic.org/"]
- ["Rahil Momin", "https://github.com/iamrahil"]
- ["Gregrory Kielian", "https://github.com/gskielian"]
- ["Etan Reisner", "https://github.com/deryni"]
translators: translators:
- ["Jinchang Ye", "https://github.com/Alwayswithme"]
- ["Chunyang Xu", "https://github.com/XuChunyang"] - ["Chunyang Xu", "https://github.com/XuChunyang"]
filename: LearnBash-cn.sh filename: LearnBash-cn.sh
lang: zh-cn lang: zh-cn
@ -23,31 +30,45 @@ Bash 是一个为 GNU 计划编写的 Unix shell是 Linux 和 Mac OS X 下的
# 如你所见,注释以 # 开头shebang 也是注释。 # 如你所见,注释以 # 开头shebang 也是注释。
# 显示 “Hello world!” # 显示 “Hello world!”
echo Hello, world! echo Hello world!
# 每一句指令以换行或分号隔开: # 每一句指令以换行或分号隔开:
echo 'This is the first line'; echo 'This is the second line' echo 'This is the first line'; echo 'This is the second line'
# 声明一个变量: # 声明一个变量:
VARIABLE="Some string" Variable="Some string"
# 下面是错误的做法: # 下面是错误的做法:
VARIABLE = "Some string" Variable = "Some string"
# Bash 会把 VARIABLE 当做一个指令,由于找不到该指令,因此这里会报错。 # Bash 会把 Variable 当做一个指令,由于找不到该指令,因此这里会报错。
# 也不可以这样:
Variable= 'Some string'
# Bash 会认为 'Some string' 是一条指令,由于找不到该指令,这里再次报错。
# (这个例子中 'Variable=' 这部分会被当作仅对 'Some string' 起作用的赋值。)
# 使用变量: # 使用变量:
echo $VARIABLE echo $Variable
echo "$VARIABLE" echo "$Variable"
echo '$VARIABLE' echo '$Variable'
# 当你赋值 (assign) 、导出 (export),或者以其他方式使用变量时,变量名前不加 $。 # 当你赋值 (assign) 、导出 (export),或者以其他方式使用变量时,变量名前不加 $。
# 如果要使用变量的值, 则要加 $。 # 如果要使用变量的值, 则要加 $。
# 注意: ' (单引号) 不会展开变量(即会屏蔽掉变量)。 # 注意: ' (单引号) 不会展开变量(即会屏蔽掉变量)。
# 在变量内部进行字符串代换 # 在变量内部进行字符串代换
echo ${VARIABLE/Some/A} echo ${Variable/Some/A}
# 会把 VARIABLE 中首次出现的 "some" 替换成 “A”。 # 会把 Variable 中首次出现的 "some" 替换成 “A”。
# 变量的截取
Length=7
echo ${Variable:0:Length}
# 这样会仅返回变量值的前7个字符
# 变量的默认值
echo ${Foo:-"DefaultValueIfFooIsMissingOrEmpty"}
# 对 null (Foo=) 和空串 (Foo="") 起作用; 零Foo=0时返回0
# 注意这仅返回默认值而不是改变变量的值
# 内置变量: # 内置变量:
# 下面的内置变量很有用 # 下面的内置变量很有用
@ -55,26 +76,37 @@ echo "Last program return value: $?"
echo "Script's PID: $$" echo "Script's PID: $$"
echo "Number of arguments: $#" echo "Number of arguments: $#"
echo "Scripts arguments: $@" echo "Scripts arguments: $@"
echo "Scripts arguments separeted in different variables: $1 $2..." echo "Scripts arguments separated in different variables: $1 $2..."
# 读取输入: # 读取输入:
echo "What's your name?" echo "What's your name?"
read NAME # 这里不需要声明新变量 read Name # 这里不需要声明新变量
echo Hello, $NAME! echo Hello, $Name!
# 通常的 if 结构看起来像这样: # 通常的 if 结构看起来像这样:
# 'man test' 可查看更多的信息 # 'man test' 可查看更多的信息
if [ $NAME -ne $USER ] if [ $Name -ne $USER ]
then then
echo "Your name is you username" echo "Your name isn't your username"
else else
echo "Your name isn't you username" echo "Your name is your username"
fi fi
# 根据上一个指令执行结果决定是否执行下一个指令 # 根据上一个指令执行结果决定是否执行下一个指令
echo "Always executed" || echo "Only executed if first command fail" echo "Always executed" || echo "Only executed if first command fails"
echo "Always executed" && echo "Only executed if first command does NOT fail" echo "Always executed" && echo "Only executed if first command does NOT fail"
# 在 if 语句中使用 && 和 || 需要多对方括号
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
# 表达式的格式如下: # 表达式的格式如下:
echo $(( 10 + 5 )) echo $(( 10 + 5 ))
@ -88,18 +120,54 @@ ls -l # 列出文件和目录的详细信息
# 用下面的指令列出当前目录下所有的 txt 文件: # 用下面的指令列出当前目录下所有的 txt 文件:
ls -l | grep "\.txt" ls -l | grep "\.txt"
# 重定向输入和输出(标准输入,标准输出,标准错误)。
# 以 ^EOF$ 作为结束标记从标准输入读取数据并覆盖 hello.py :
cat > hello.py << EOF
#!/usr/bin/env python
from __future__ import print_function
import sys
print("#stdout", file=sys.stdout)
print("#stderr", file=sys.stderr)
for line in sys.stdin:
print(line, file=sys.stdout)
EOF
# 重定向可以到输出,输入和错误输出。 # 重定向可以到输出,输入和错误输出。
python2 hello.py < "input.in" python hello.py < "input.in"
python2 hello.py > "output.out" python hello.py > "output.out"
python2 hello.py 2> "error.err" python hello.py 2> "error.err"
python hello.py > "output-and-error.log" 2>&1
python hello.py > /dev/null 2>&1
# > 会覆盖已存在的文件, >> 会以累加的方式输出文件中。 # > 会覆盖已存在的文件, >> 会以累加的方式输出文件中。
python hello.py >> "output.out" 2>> "error.err"
# 覆盖 output.out , 追加 error.err 并统计行数
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
wc -l output.out error.err
# 运行指令并打印文件描述符 (比如 /dev/fd/123
# 具体可查看: man fd
echo <(echo "#helloworld")
# 以 "#helloworld" 覆盖 output.out:
cat > output.out <(echo "#helloworld")
echo "#helloworld" > output.out
echo "#helloworld" | cat > output.out
echo "#helloworld" | tee output.out >/dev/null
# 清理临时文件并显示详情(增加 '-i' 选项启用交互模式)
rm -v output.out error.err output-and-error.log
# 一个指令可用 $( ) 嵌套在另一个指令内部: # 一个指令可用 $( ) 嵌套在另一个指令内部:
# 以下的指令会打印当前目录下的目录和文件总数 # 以下的指令会打印当前目录下的目录和文件总数
echo "There are $(ls | wc -l) items here." echo "There are $(ls | wc -l) items here."
# 反引号 `` 起相同作用,但不允许嵌套
# 优先使用 $( ).
echo "There are `ls | wc -l` items here."
# Bash 的 case 语句与 Java 和 C++ 中的 switch 语句类似: # Bash 的 case 语句与 Java 和 C++ 中的 switch 语句类似:
case "$VARIABLE" in case "$Variable" in
# 列出需要匹配的字符串 # 列出需要匹配的字符串
0) echo "There is a zero.";; 0) echo "There is a zero.";;
1) echo "There is a one.";; 1) echo "There is a one.";;
@ -107,11 +175,37 @@ case "$VARIABLE" in
esac esac
# 循环遍历给定的参数序列: # 循环遍历给定的参数序列:
# 变量$VARIABLE 的值会被打印 3 次。 # 变量$Variable 的值会被打印 3 次。
# 注意 ` ` 和 $( ) 等价。seq 返回长度为 3 的数组。 for Variable in {1..3}
for VARIABLE in `seq 3`
do do
echo "$VARIABLE" echo "$Variable"
done
# 或传统的 “for循环”
for ((a=1; a <= 3; a++))
do
echo $a
done
# 也可以用于文件
# 用 cat 输出 file1 和 file2 内容
for Variable in file1 file2
do
cat "$Variable"
done
# 或作用于其他命令的输出
# 对 ls 输出的文件执行 cat 指令。
for Output in $(ls)
do
cat "$Output"
done
# while 循环:
while [ true ]
do
echo "loop body here..."
break
done done
# 你也可以使用函数 # 你也可以使用函数
@ -132,17 +226,52 @@ bar ()
} }
# 调用函数 # 调用函数
foo "My name is" $NAME foo "My name is" $Name
# 有很多有用的指令需要学习: # 有很多有用的指令需要学习:
tail -n 10 file.txt
# 打印 file.txt 的最后 10 行 # 打印 file.txt 的最后 10 行
head -n 10 file.txt tail -n 10 file.txt
# 打印 file.txt 的前 10 行 # 打印 file.txt 的前 10 行
sort file.txt head -n 10 file.txt
# 将 file.txt 按行排序 # 将 file.txt 按行排序
uniq -d file.txt sort file.txt
# 报告或忽略重复的行,用选项 -d 打印重复的行 # 报告或忽略重复的行,用选项 -d 打印重复的行
cut -d ',' -f 1 file.txt uniq -d file.txt
# 打印每行中 ',' 之前内容 # 打印每行中 ',' 之前内容
cut -d ',' -f 1 file.txt
# 将 file.txt 文件所有 'okay' 替换为 'great', (兼容正则表达式)
sed -i 's/okay/great/g' file.txt
# 将 file.txt 中匹配正则的行打印到标准输出
# 这里打印以 "foo" 开头, "bar" 结尾的行
grep "^foo.*bar$" file.txt
# 使用选项 "-c" 统计行数
grep -c "^foo.*bar$" file.txt
# 如果只是要按字面形式搜索字符串而不是按正则表达式,使用 fgrep (或 grep -F)
fgrep "^foo.*bar$" file.txt
# 以 bash 内建的 'help' 指令阅读 Bash 自带文档:
help
help help
help for
help return
help source
help .
# 用 mam 指令阅读相关的 Bash 手册
apropos bash
man 1 bash
man bash
# 用 info 指令查阅命令的 info 文档 info 中按 ? 显示帮助信息)
apropos info | grep '^info.*('
man info
info info
info 5 info
# 阅读 Bash 的 info 文档:
info bash
info bash 'Bash Features'
info bash 6
info --apropos bash
``` ```

View File

@ -0,0 +1,420 @@
---
language: Groovy
filename: learngroovy-cn.groovy
contributors:
- ["Roberto Pérez Alcolea", "http://github.com/rpalcolea"]
translators:
- ["Todd Gao", "http://github.com/7c00"]
lang: zh-cn
---
Groovy - Java平台的动态语言。[了解更多。](http://www.groovy-lang.org/)
```groovy
/*
安装:
1) 安装 GVM - http://gvmtool.net/
2) 安装 Groovy gvm install groovy
3) 启动 groovy 控制台,键入: groovyConsole
*/
// 双斜线开始的是单行注释
/*
像这样的是多行注释
*/
// Hello World
println "Hello world!"
/*
变量:
可以给变量赋值,以便稍后使用
*/
def x = 1
println x
x = new java.util.Date()
println x
x = -3.1499392
println x
x = false
println x
x = "Groovy!"
println x
/*
集合和映射
*/
//创建一个空的列表
def technologies = []
/*** 往列表中增加一个元素 ***/
// 和Java一样
technologies.add("Grails")
// 左移添加,返回该列表
technologies << "Groovy"
// 增加多个元素
technologies.addAll(["Gradle","Griffon"])
/*** 从列表中删除元素 ***/
// 和Java一样
technologies.remove("Griffon")
// 减号也行
technologies = technologies - 'Grails'
/*** 遍历列表 ***/
// 遍历列表中的元素
technologies.each { println "Technology: $it"}
technologies.eachWithIndex { it, i -> println "$i: $it"}
/*** 检查列表内容 ***/
//判断列表是否包含某元素返回boolean
contained = technologies.contains( 'Groovy' )
// 或
contained = 'Groovy' in technologies
// 检查多个元素
technologies.containsAll(['Groovy','Grails'])
/*** 列表排序 ***/
// 排序列表(修改原列表)
technologies.sort()
// 要想不修改原列表,可以这样:
sortedTechnologies = technologies.sort( false )
/*** 列表操作 ***/
//替换列表元素
Collections.replaceAll(technologies, 'Gradle', 'gradle')
//打乱列表
Collections.shuffle(technologies, new Random())
//清空列表
technologies.clear()
//创建空的映射
def devMap = [:]
//增加值
devMap = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
devMap.put('lastName','Perez')
//遍历映射元素
devMap.each { println "$it.key: $it.value" }
devMap.eachWithIndex { it, i -> println "$i: $it"}
//判断映射是否包含某键
assert devMap.containsKey('name')
//判断映射是否包含某值
assert devMap.containsValue('Roberto')
//取得映射所有的键
println devMap.keySet()
//取得映射所有的值
println devMap.values()
/*
Groovy Beans
GroovyBeans 是 JavaBeans但使用了更简单的语法
Groovy 被编译为字节码时,遵循下列规则。
* 如果一个名字声明时带有访问修饰符public, private, 或者 protected
则会生成一个字段field
* 名字声明时没有访问修饰符则会生成一个带有public getter和setter的
private字段即属性property
* 如果一个属性声明为final则会创建一个final的private字段但不会生成setter。
* 可以声明一个属性的同时定义自己的getter和setter。
* 可以声明具有相同名字的属性和字段,该属性会使用该字段。
* 如果要定义private或protected属性必须提供声明为private或protected的getter
和setter。
* 如果使用显式或隐式的 this例如 this.foo, 或者 foo访问类的在编译时定义的属性
Groovy会直接访问对应字段而不是使用getter或者setter
* 如果使用显式或隐式的 foo 访问一个不存在的属性Groovy会通过元类meta class
访问它,这可能导致运行时错误。
*/
class Foo {
// 只读属性
final String name = "Roberto"
// 只读属性有public getter和protected setter
String language
protected void setLanguage(String language) { this.language = language }
// 动态类型属性
def lastName
}
/*
逻辑分支和循环
*/
//Groovy支持常见的if - else语法
def x = 3
if(x==1) {
println "One"
} else if(x==2) {
println "Two"
} else {
println "X greater than Two"
}
//Groovy也支持三元运算符
def y = 10
def x = (y > 1) ? "worked" : "failed"
assert x == "worked"
//for循环
//使用区间range遍历
def x = 0
for (i in 0 .. 30) {
x += i
}
//遍历列表
x = 0
for( i in [5,3,2,1] ) {
x += i
}
//遍历数组
array = (0..20).toArray()
x = 0
for (i in array) {
x += i
}
//遍历映射
def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
x = 0
for ( e in map ) {
x += e.value
}
/*
运算符
在Groovy中以下常用运算符支持重载
http://www.groovy-lang.org/operators.html#Operator-Overloading
实用的groovy运算符
*/
//展开spread运算符对聚合对象的所有元素施加操作
def technologies = ['Groovy','Grails','Gradle']
technologies*.toUpperCase() // 相当于 technologies.collect { it?.toUpperCase() }
//安全导航safe navigation运算符用来避免NullPointerException
def user = User.get(1)
def username = user?.username
/*
闭包
Groovy闭包好比代码块或者方法指针它是一段代码定义可以以后执行。
更多信息见http://www.groovy-lang.org/closures.html
*/
//例子:
def clos = { println "Hello World!" }
println "Executing the Closure:"
clos()
//传参数给闭包
def sum = { a, b -> println a+b }
sum(2,4)
//闭包可以引用参数列表以外的变量
def x = 5
def multiplyBy = { num -> num * x }
println multiplyBy(10)
// 只有一个参数的闭包可以省略参数的定义
def clos = { print it }
clos( "hi" )
/*
Groovy可以记忆闭包结果 [1][2][3]
*/
def cl = {a, b ->
sleep(3000) // 模拟费时操作
a + b
}
mem = cl.memoize()
def callClosure(a, b) {
def start = System.currentTimeMillis()
mem(a, b)
println "Inputs(a = $a, b = $b) - took ${System.currentTimeMillis() - start} msecs."
}
callClosure(1, 2)
callClosure(1, 2)
callClosure(2, 3)
callClosure(2, 3)
callClosure(3, 4)
callClosure(3, 4)
callClosure(1, 2)
callClosure(2, 3)
callClosure(3, 4)
/*
Expando
Expando类是一种动态bean类可以给它的实例添加属性和添加闭包作为方法
http://mrhaki.blogspot.mx/2009/10/groovy-goodness-expando-as-dynamic-bean.html
*/
def user = new Expando(name:"Roberto")
assert 'Roberto' == user.name
user.lastName = 'Pérez'
assert 'Pérez' == user.lastName
user.showInfo = { out ->
out << "Name: $name"
out << ", Last name: $lastName"
}
def sw = new StringWriter()
println user.showInfo(sw)
/*
元编程(MOP)
*/
//使用ExpandoMetaClass增加行为
String.metaClass.testAdd = {
println "we added this"
}
String x = "test"
x?.testAdd()
//拦截方法调用
class Test implements GroovyInterceptable {
def sum(Integer x, Integer y) { x + y }
def invokeMethod(String name, args) {
System.out.println "Invoke method $name with args: $args"
}
}
def test = new Test()
test?.sum(2,3)
test?.multiply(2,3)
//Groovy支持propertyMissing来处理属性解析尝试
class Foo {
def propertyMissing(String name) { name }
}
def f = new Foo()
assertEquals "boo", f.boo
/*
类型检查和静态编译
Groovy天生是并将永远是一门动态语言但也支持类型检查和静态编译
更多: http://www.infoq.com/articles/new-groovy-20
*/
//类型检查
import groovy.transform.TypeChecked
void testMethod() {}
@TypeChecked
void test() {
testMeethod()
def name = "Roberto"
println naameee
}
//另一例子
import groovy.transform.TypeChecked
@TypeChecked
Integer test() {
Integer num = "1"
Integer[] numbers = [1,2,3,4]
Date date = numbers[1]
return "Test"
}
//静态编译例子
import groovy.transform.CompileStatic
@CompileStatic
int sum(int x, int y) {
x + y
}
assert sum(2,5) == 7
```
## 进阶资源
[Groovy文档](http://www.groovy-lang.org/documentation.html)
[Groovy web console](http://groovyconsole.appspot.com/)
加入[Groovy用户组](http://www.groovy-lang.org/usergroups.html)
## 图书
* [Groovy Goodness] (https://leanpub.com/groovy-goodness-notebook)
* [Groovy in Action] (http://manning.com/koenig2/)
* [Programming Groovy 2: Dynamic Productivity for the Java Developer] (http://shop.oreilly.com/product/9781937785307.do)
[1] http://roshandawrani.wordpress.com/2010/10/18/groovy-new-feature-closures-can-now-memorize-their-results/
[2] http://www.solutionsiq.com/resources/agileiq-blog/bid/72880/Programming-with-Groovy-Trampoline-and-Memoize
[3] http://mrhaki.blogspot.mx/2011/05/groovy-goodness-cache-closure-results.html

View File

@ -341,7 +341,7 @@ var myFunc = myObj.myFunc;
myFunc(); // = undefined myFunc(); // = undefined
// 相应的,一个函数也可以被指定为一个对象的方法,并且可以通过`this`访问 // 相应的,一个函数也可以被指定为一个对象的方法,并且可以通过`this`访问
// 这个对象的成员,即使在数被定义时并没有依附在对象上。 // 这个对象的成员,即使在数被定义时并没有依附在对象上。
var myOtherFunc = function(){ var myOtherFunc = function(){
return this.myString.toUpperCase(); return this.myString.toUpperCase();
} }