mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-23 15:24:09 +03:00
Merge remote-tracking branch 'upstream/master'
Conflicts: perl6.html.markdown
This commit is contained in:
commit
2162639cd9
@ -10,6 +10,7 @@ contributors:
|
||||
- ["Anton Strömkvist", "http://lutic.org/"]
|
||||
- ["Rahil Momin", "https://github.com/iamrahil"]
|
||||
- ["Gregrory Kielian", "https://github.com/gskielian"]
|
||||
- ["Etan Reisner", "https://github.com/deryni"]
|
||||
filename: LearnBash.sh
|
||||
---
|
||||
|
||||
@ -31,32 +32,41 @@ echo Hello world!
|
||||
echo 'This is the first line'; echo 'This is the second line'
|
||||
|
||||
# Declaring a variable looks like this:
|
||||
VARIABLE="Some string"
|
||||
Variable="Some string"
|
||||
|
||||
# But not like this:
|
||||
VARIABLE = "Some string"
|
||||
# Bash will decide that VARIABLE is a command it must execute and give an error
|
||||
# because it couldn't be found.
|
||||
Variable = "Some string"
|
||||
# Bash will decide that Variable is a command it must execute and give an error
|
||||
# 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:
|
||||
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
|
||||
# its name without $. If you want to use variable's value, you should use $.
|
||||
# Note that ' (single quote) won't expand the variables!
|
||||
|
||||
# String substitution in variables
|
||||
echo ${VARIABLE/Some/A}
|
||||
# This will substitute the first occurance of "Some" with "A"
|
||||
echo ${Variable/Some/A}
|
||||
# This will substitute the first occurrence of "Some" with "A"
|
||||
|
||||
# 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
|
||||
|
||||
# Default value for variable
|
||||
echo ${FOO:-"DefaultValueIfFOOIsMissingOrEmpty"}
|
||||
# This works for null (FOO=), empty string (FOO=""), zero (FOO=0) returns 0
|
||||
echo ${Foo:-"DefaultValueIfFooIsMissingOrEmpty"}
|
||||
# This works for null (Foo=) and empty string (Foo=""); zero (Foo=0) returns 0.
|
||||
# Note that it only returns default value and doesn't change variable value.
|
||||
|
||||
# Builtin variables:
|
||||
# There are some useful builtin variables, like
|
||||
@ -64,16 +74,16 @@ echo "Last program return value: $?"
|
||||
echo "Script's PID: $$"
|
||||
echo "Number of 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:
|
||||
echo "What's your name?"
|
||||
read NAME # Note that we didn't need to declare a new variable
|
||||
echo Hello, $NAME!
|
||||
read Name # Note that we didn't need to declare a new variable
|
||||
echo Hello, $Name!
|
||||
|
||||
# We have the usual if structure:
|
||||
# use 'man test' for more info about conditionals
|
||||
if [ $NAME -ne $USER ]
|
||||
if [ $Name -ne $USER ]
|
||||
then
|
||||
echo "Your name isn't your username"
|
||||
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"
|
||||
|
||||
# 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
|
||||
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
|
||||
|
||||
if [ $NAME == "Daniya" ] || [ $NAME == "Zach" ]
|
||||
if [ $Name == "Daniya" ] || [ $Name == "Zach" ]
|
||||
then
|
||||
echo "This will run if $NAME is Daniya OR Zach."
|
||||
echo "This will run if $Name is Daniya OR Zach."
|
||||
fi
|
||||
|
||||
# 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 ">>":
|
||||
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
|
||||
wc -l output.out error.err
|
||||
|
||||
@ -142,7 +152,7 @@ wc -l output.out error.err
|
||||
# see: man fd
|
||||
echo <(echo "#helloworld")
|
||||
|
||||
# Overwrite output.txt with "#helloworld":
|
||||
# Overwrite output.out with "#helloworld":
|
||||
cat > output.out <(echo "#helloworld")
|
||||
echo "#helloworld" > 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."
|
||||
|
||||
# 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
|
||||
0) echo "There is a zero.";;
|
||||
1) echo "There is a one.";;
|
||||
@ -169,10 +179,10 @@ case "$VARIABLE" in
|
||||
esac
|
||||
|
||||
# for loops iterate for as many arguments given:
|
||||
# The contents of $VARIABLE is printed three times.
|
||||
for VARIABLE in {1..3}
|
||||
# The contents of $Variable is printed three times.
|
||||
for Variable in {1..3}
|
||||
do
|
||||
echo "$VARIABLE"
|
||||
echo "$Variable"
|
||||
done
|
||||
|
||||
# Or write it the "traditional for loop" way:
|
||||
@ -183,16 +193,16 @@ done
|
||||
|
||||
# They can also be used to act on files..
|
||||
# This will run the command 'cat' on file1 and file2
|
||||
for VARIABLE in file1 file2
|
||||
for Variable in file1 file2
|
||||
do
|
||||
cat "$VARIABLE"
|
||||
cat "$Variable"
|
||||
done
|
||||
|
||||
# ..or the output from a command
|
||||
# This will cat the output from ls.
|
||||
for OUTPUT in $(ls)
|
||||
for Output in $(ls)
|
||||
do
|
||||
cat "$OUTPUT"
|
||||
cat "$Output"
|
||||
done
|
||||
|
||||
# while loop:
|
||||
@ -220,7 +230,7 @@ bar ()
|
||||
}
|
||||
|
||||
# Calling your function
|
||||
foo "My name is" $NAME
|
||||
foo "My name is" $Name
|
||||
|
||||
# There are a lot of useful commands you should learn:
|
||||
# prints last 10 lines of file.txt
|
||||
|
@ -32,8 +32,7 @@ one of the most widely-used programming languages.
|
||||
// variable declarations, primitive types, and functions.
|
||||
|
||||
// Just like in C, your program's entry point is a function called
|
||||
// main with an integer return type,
|
||||
// though void main() is also accepted by most compilers (gcc, clang, etc.)
|
||||
// main with an integer return type.
|
||||
// This value serves as the program's exit status.
|
||||
// See http://en.wikipedia.org/wiki/Exit_status for more information.
|
||||
int main(int argc, char** argv)
|
||||
@ -289,7 +288,7 @@ public:
|
||||
|
||||
// Functions can also be defined inside the class body.
|
||||
// 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.
|
||||
// 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.
|
||||
|
||||
// Class member functions are usually implemented in .cpp files.
|
||||
void Dog::Dog()
|
||||
Dog::Dog()
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
void Dog::~Dog()
|
||||
Dog::~Dog()
|
||||
{
|
||||
cout << "Goodbye " << name << "\n";
|
||||
}
|
||||
@ -333,7 +332,7 @@ int main() {
|
||||
Dog myDog; // prints "A dog has been constructed"
|
||||
myDog.setName("Barkley");
|
||||
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;
|
||||
} // prints "Goodbye Barkley"
|
||||
|
||||
@ -342,7 +341,7 @@ int main() {
|
||||
// This class inherits everything public and protected from the Dog class
|
||||
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
|
||||
// http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
|
||||
@ -426,13 +425,92 @@ int main () {
|
||||
Point up (0,1);
|
||||
Point right (1,0);
|
||||
// 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;
|
||||
// Prints "Result is upright (1,1)"
|
||||
cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
|
||||
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
|
||||
/////////////////////
|
||||
@ -441,12 +519,13 @@ int main () {
|
||||
// (see http://en.cppreference.com/w/cpp/error/exception)
|
||||
// but any type can be thrown an as exception
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
|
||||
// All exceptions thrown inside the _try_ block can be caught by subsequent
|
||||
// _catch_ handlers.
|
||||
try {
|
||||
// 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 (const std::exception& ex)
|
||||
@ -537,7 +616,7 @@ void doSomethingWithAFile(const char* filename)
|
||||
{
|
||||
FILE* fh = fopen(filename, "r"); // Open the file in read mode
|
||||
if (fh == nullptr)
|
||||
throw std::exception("Could not open the file.");
|
||||
throw std::runtime_error("Could not open the file.");
|
||||
|
||||
try {
|
||||
doSomethingWithTheFile(fh);
|
||||
@ -586,8 +665,56 @@ void doSomethingWithAFile(const std::string& filename)
|
||||
// vector (i.e. self-resizing array), hash maps, and so on
|
||||
// all automatically destroy their contents when they fall out of scope.
|
||||
// - 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
|
||||
<http://cppreference.com/w/cpp>
|
||||
|
@ -22,7 +22,7 @@ and often automatically.
|
||||
; Clojure is written in "forms", which are just
|
||||
; 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.
|
||||
|
||||
; The first call in a file should be ns, to set the namespace
|
||||
|
@ -155,8 +155,8 @@ Now, your handlers may utilize query parameters:
|
||||
```clojure
|
||||
(defroutes myapp
|
||||
(GET "/posts" req
|
||||
(let [title (get (:params req) "title")
|
||||
author (get (:params req) "author")]
|
||||
(let [title (get (:params req) :title)
|
||||
author (get (:params req) :author)]
|
||||
(str "Title: " title ", Author: " author))))
|
||||
```
|
||||
|
||||
@ -165,8 +165,8 @@ Or, for POST and PUT requests, form parameters as well
|
||||
```clojure
|
||||
(defroutes myapp
|
||||
(POST "/posts" req
|
||||
(let [title (get (:params req) "title")
|
||||
author (get (:params req) "author")]
|
||||
(let [title (get (:params req) :title)
|
||||
author (get (:params req) :author)]
|
||||
(str "Title: " title ", Author: " author))))
|
||||
```
|
||||
|
||||
|
@ -29,7 +29,7 @@ filename: learn-emacs-lisp.el
|
||||
;; I hereby decline any responsability. Have fun!
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;;
|
||||
;; Fire up Emacs.
|
||||
;;
|
||||
;; Hit the `q' key to dismiss the welcome message.
|
||||
@ -42,9 +42,9 @@ filename: learn-emacs-lisp.el
|
||||
;; The scratch buffer is the default buffer when opening Emacs.
|
||||
;; You are never editing files: you are editing buffers that you
|
||||
;; can save to a file.
|
||||
;;
|
||||
;;
|
||||
;; "Lisp interaction" refers to a set of commands available here.
|
||||
;;
|
||||
;;
|
||||
;; Emacs has a built-in set of commands available in every buffer,
|
||||
;; and several subsets of commands available when you activate a
|
||||
;; specific mode. Here we use the `lisp-interaction-mode', which
|
||||
@ -109,7 +109,7 @@ filename: learn-emacs-lisp.el
|
||||
;; The empty parentheses in the function's definition means that
|
||||
;; it does not accept arguments. But always using `my-name' is
|
||||
;; boring, let's tell the function to accept one argument (here
|
||||
;; the argument is called "name"):
|
||||
;; the argument is called "name"):
|
||||
|
||||
(defun hello (name) (insert "Hello " name))
|
||||
;; `C-xC-e' => hello
|
||||
@ -305,7 +305,7 @@ filename: learn-emacs-lisp.el
|
||||
(defun boldify-names ()
|
||||
(switch-to-buffer-other-window "*test*")
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "Bonjour \\([^!]+\\)!" nil 't)
|
||||
(while (re-search-forward "Bonjour \\(.+\\)!" nil 't)
|
||||
(add-text-properties (match-beginning 1)
|
||||
(match-end 1)
|
||||
(list 'face 'bold)))
|
||||
@ -318,7 +318,7 @@ filename: learn-emacs-lisp.el
|
||||
;; The regular expression is "Bonjour \\(.+\\)!" and it reads:
|
||||
;; the string "Bonjour ", and
|
||||
;; a group of | this is the \\( ... \\) construct
|
||||
;; any character not ! | this is the [^!]
|
||||
;; any character | this is the .
|
||||
;; possibly repeated | this is the +
|
||||
;; and the "!" string.
|
||||
|
||||
|
@ -195,7 +195,7 @@ cond do
|
||||
"But I will"
|
||||
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
|
||||
1 + 1 == 3 ->
|
||||
"I will never be seen"
|
||||
|
@ -18,7 +18,7 @@ filename: learnerlang.erl
|
||||
% Periods (`.`) (followed by whitespace) separate entire functions and
|
||||
% expressions in the shell.
|
||||
% 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.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
@ -27,20 +27,20 @@ filename: learnerlang.erl
|
||||
|
||||
Num = 42. % All variable names must start with an uppercase letter.
|
||||
|
||||
% Erlang has single assignment variables, if you try to assign a different value
|
||||
% to the variable `Num`, you’ll get an error.
|
||||
% Erlang has single-assignment variables; if you try to assign a different
|
||||
% value to the variable `Num`, you’ll get an error.
|
||||
Num = 43. % ** exception error: no match of right hand side value 43
|
||||
|
||||
% In most languages, `=` denotes an assignment statement. In Erlang, however,
|
||||
% `=` denotes a pattern matching operation. `Lhs = Rhs` really means this:
|
||||
% evaluate the right side (Rhs), and then match the result against the pattern
|
||||
% on the left side (Lhs).
|
||||
% `=` denotes a pattern-matching operation. `Lhs = Rhs` really means this:
|
||||
% evaluate the right side (`Rhs`), and then match the result against the
|
||||
% pattern on the left side (`Lhs`).
|
||||
Num = 7 * 6.
|
||||
|
||||
% Floating point number.
|
||||
% Floating-point number.
|
||||
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
|
||||
% characters or the underscore (`_`) or at (`@`) sign.
|
||||
Hello = hello.
|
||||
@ -53,34 +53,34 @@ AtomWithSpace = 'some atom with space'.
|
||||
% Tuples are similar to structs in C.
|
||||
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 `=`.
|
||||
{point, X, Y} = Point. % X = 10, Y = 45
|
||||
|
||||
% We can use `_` as a placeholder for variables that we’re not interested in.
|
||||
% The symbol `_` is called an anonymous variable. Unlike regular variables,
|
||||
% several occurrences of _ in the same pattern don’t have to bind to the same
|
||||
% value.
|
||||
% several occurrences of `_` in the same pattern don’t have to bind to the
|
||||
% same value.
|
||||
Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.
|
||||
{_, {_, {_, Who}, _}, _} = Person. % Who = joe
|
||||
|
||||
% We create a list by enclosing the list elements in square brackets and
|
||||
% separating them with commas.
|
||||
% 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
|
||||
% head from the list, what’s left is called the tail of the list.
|
||||
% The first element of a list is the head of the list. If you imagine removing
|
||||
% the head from the list, what’s left is called the tail of the list.
|
||||
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`.
|
||||
% The vertical bar (`|`) separates the head of a list from its tail.
|
||||
% `[]` 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`
|
||||
% are unbound variables, will extract the head of the list into `X` and the tail
|
||||
% of the list into `Y`.
|
||||
[FirstThing|OtherThingsToBuy] = ThingsToBuy.
|
||||
% 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.
|
||||
% Strings are enclosed in double quotation marks (`"`).
|
||||
@ -117,17 +117,19 @@ c(geometry). % {ok,geometry}
|
||||
geometry:area({rectangle, 10, 5}). % 50
|
||||
geometry:area({circle, 1.4}). % 6.15752
|
||||
|
||||
% In Erlang, two functions with the same name and different arity (number of arguments)
|
||||
% in the same module represent entirely different functions.
|
||||
% In Erlang, two functions with the same name and different arity (number of
|
||||
% arguments) in the same module represent entirely different functions.
|
||||
-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([], N) -> N;
|
||||
sum([H|T], N) -> sum(T, H+N).
|
||||
|
||||
% Funs are "anonymous" functions. They are called this way because they have 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>
|
||||
% Funs are "anonymous" functions. They are called this way because they have
|
||||
% 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(2). % 4
|
||||
|
||||
% 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
|
||||
% from the list `L`."
|
||||
L = [1,2,3,4,5].
|
||||
[2*X || X <- L]. % [2,4,6,8,10]
|
||||
% A list comprehension can have generators and filters which select subset of the generated values.
|
||||
[2 * X || X <- L]. % [2,4,6,8,10]
|
||||
% 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]
|
||||
|
||||
% 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 (`,`).
|
||||
% 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) -> false.
|
||||
is_dog(A) when is_atom(A), A =:= dog -> true;
|
||||
is_dog(A) -> false.
|
||||
|
||||
% 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, ...` evaluates to true.
|
||||
is_pet(A) when is_dog(A); is_cat(A) -> true;
|
||||
is_pet(A) -> false.
|
||||
% We won't dwell on the `=:=` operator here; just be aware that it is used to
|
||||
% check whether two Erlang expressions have the same value *and* the same type.
|
||||
% Contrast this behaviour to that of the `==` operator:
|
||||
1 + 2 =:= 3. % true
|
||||
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
|
||||
% tuple.
|
||||
@ -188,7 +205,7 @@ X = #todo{}.
|
||||
X1 = #todo{status = urgent, text = "Fix errata in book"}.
|
||||
% #todo{status = urgent, who = joe, text = "Fix errata in book"}
|
||||
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.
|
||||
% `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
|
||||
end.
|
||||
|
||||
% Warning: at least one of the guards in the `if` expression must evaluate to true;
|
||||
% otherwise, an exception will be raised.
|
||||
% Warning: at least one of the guards in the `if` expression must evaluate to
|
||||
% `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
|
||||
% explicitly in code by calling `throw(Exception)`, `exit(Exception)` or
|
||||
% explicitly in code by calling `throw(Exception)`, `exit(Exception)`, or
|
||||
% `erlang:error(Exception)`.
|
||||
generate_exception(1) -> a;
|
||||
generate_exception(2) -> throw(a);
|
||||
@ -227,7 +244,7 @@ generate_exception(4) -> {'EXIT', a};
|
||||
generate_exception(5) -> erlang:error(a).
|
||||
|
||||
% 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) ->
|
||||
try generate_exception(N) of
|
||||
Val -> {N, normal, Val}
|
||||
@ -241,23 +258,24 @@ catcher(N) ->
|
||||
% exception, it is converted into a tuple that describes the error.
|
||||
catcher(N) -> catch generate_exception(N).
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% 4. Concurrency
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% 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.
|
||||
|
||||
% 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.
|
||||
|
||||
F = fun() -> 2 + 2 end. % #Fun<erl_eval.20.67289768>
|
||||
spawn(F). % <0.44.0>
|
||||
|
||||
% `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.
|
||||
% For all of this to be useful we need to be able to receive messages. This is
|
||||
% `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.
|
||||
% For all of this to be useful, we need to be able to receive messages. This is
|
||||
% achieved with the `receive` mechanism:
|
||||
|
||||
-module(calculateGeometry).
|
||||
@ -272,12 +290,13 @@ calculateArea() ->
|
||||
io:format("We can only calculate area of rectangles or circles.")
|
||||
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).
|
||||
CalculateArea = spawn(calculateGeometry, calculateArea, []).
|
||||
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>
|
||||
|
||||
```
|
||||
|
327
fr-fr/erlang-fr.html.markdown
Normal file
327
fr-fr/erlang-fr.html.markdown
Normal 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)` où `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)
|
62
fr-fr/json-fr.html.markdown
Normal file
62
fr-fr/json-fr.html.markdown
Normal 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
747
fr-fr/r-fr.html.markdown
Normal 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
|
174
fr-fr/typescript-fr.html.markdown
Normal file
174
fr-fr/typescript-fr.html.markdown
Normal 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/)
|
@ -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 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
|
||||
|
||||
* [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/)
|
||||
@ -131,6 +136,10 @@ $ git help -a
|
||||
$ git help add
|
||||
$ git help commit
|
||||
$ git help init
|
||||
# or git <command_here> --help
|
||||
$ git add --help
|
||||
$ git commit --help
|
||||
$ git init --help
|
||||
```
|
||||
|
||||
### status
|
||||
@ -149,8 +158,8 @@ $ git help status
|
||||
|
||||
### add
|
||||
|
||||
To add files to the current working tree/directory/repo. If you do not `git add` new files to the
|
||||
working tree/directory, they will not be included in commits!
|
||||
To add files to the staging area/index. If you do not `git add` new files to the
|
||||
staging area/index, they will not be included in commits!
|
||||
|
||||
```bash
|
||||
# add a file in your current working directory
|
||||
@ -163,6 +172,8 @@ $ git add /path/to/file/HelloWorld.c
|
||||
$ git add ./*.java
|
||||
```
|
||||
|
||||
This only adds a file to the staging area/index, it doesn't commit it to the working directory/repo.
|
||||
|
||||
### branch
|
||||
|
||||
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/)
|
||||
|
||||
* [Git - the simple guide](http://rogerdudler.github.io/git-guide/index.html)
|
||||
|
||||
* [Pro Git](http://www.git-scm.com/book/en/v2)
|
||||
|
@ -6,7 +6,7 @@ contributors:
|
||||
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
|
||||
|
||||
@ -231,7 +231,7 @@ for ( e in map ) {
|
||||
Operators
|
||||
|
||||
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
|
||||
*/
|
||||
@ -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
|
||||
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:
|
||||
def clos = { println "Hello World!" }
|
||||
@ -405,11 +405,11 @@ assert sum(2,5) == 7
|
||||
|
||||
## 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/)
|
||||
|
||||
Join a [Groovy user group](http://groovy.codehaus.org/User+Groups)
|
||||
Join a [Groovy user group](http://www.groovy-lang.org/usergroups.html)
|
||||
|
||||
## Books
|
||||
|
||||
|
@ -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
|
||||
|
||||
-- This is now the same as
|
||||
(2 * 3 + (2 * 2 + (2 * 1 + 4)))
|
||||
(2 * 1 + (2 * 2 + (2 * 3 + 4)))
|
||||
|
||||
----------------------------------------------------
|
||||
-- 7. Data Types
|
||||
|
@ -323,7 +323,7 @@ class LearnHaxe3{
|
||||
var l = 0;
|
||||
do{
|
||||
trace("do statement always runs at least once");
|
||||
} while (i > 0);
|
||||
} while (l > 0);
|
||||
|
||||
// for loop
|
||||
/*
|
||||
@ -340,7 +340,7 @@ class LearnHaxe3{
|
||||
// (more on ranges later as well)
|
||||
var n = ['foo', 'bar', 'baz'];
|
||||
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 "spot" : favorite_thing = "tennis ball";
|
||||
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
|
||||
// that will match anything.
|
||||
@ -397,7 +397,7 @@ class LearnHaxe3{
|
||||
// if statements
|
||||
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) {
|
||||
case "fido" : "teddy";
|
||||
@ -495,8 +495,10 @@ class LearnHaxe3{
|
||||
// foo_instance.public_read = 4; // this will throw an error if uncommented:
|
||||
// trace(foo_instance.public_write); // as will this.
|
||||
|
||||
trace(foo_instance + " is the value for foo_instance"); // calls the toString method
|
||||
trace(foo_instance.toString() + " is the value for foo_instance.toString()"); // same thing
|
||||
// calls the toString method:
|
||||
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{
|
||||
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_write (null, default): Int; // or public write
|
||||
public var public_read (default, null): Int; // enable only public read
|
||||
public var public_write (null, default): Int; // or only public write
|
||||
public var property (get, set): Int; // use this style to enable getters/setters
|
||||
|
||||
// private variables are not available outside the class.
|
||||
@ -534,9 +536,10 @@ class FooClass extends BarClass implements BarInterface{
|
||||
|
||||
// a public constructor
|
||||
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;
|
||||
|
||||
}
|
||||
|
275
it-it/bash-it.html.markdown
Normal file
275
it-it/bash-it.html.markdown
Normal 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
720
it-it/c++-it.html.markdown
Normal 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>
|
62
it-it/json-it.html.markdown
Normal file
62
it-it/json-it.html.markdown
Normal 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."
|
||||
}
|
||||
```
|
@ -1,16 +1,16 @@
|
||||
---
|
||||
|
||||
language: java
|
||||
contributors:
|
||||
- ["Jake Prather", "http://github.com/JakeHP"]
|
||||
- ["Madison Dickson", "http://github.com/mix3d"]
|
||||
- ["Jakukyo Friel", "http://weakish.github.io"]
|
||||
- ["Madison Dickson", "http://github.com/mix3d"]
|
||||
- ["Simon Morgan", "http://sjm.io/"]
|
||||
filename: LearnJava.java
|
||||
|
||||
---
|
||||
|
||||
Java is a general-purpose, concurrent, class-based, object-oriented computer programming language.
|
||||
[Read more here.](http://docs.oracle.com/javase/tutorial/java/index.html)
|
||||
Java is a general-purpose, concurrent, class-based, object-oriented computer
|
||||
programming language.
|
||||
[Read more here.](http://docs.oracle.com/javase/tutorial/java/)
|
||||
|
||||
```java
|
||||
// Single-line comments start with //
|
||||
@ -31,17 +31,17 @@ import java.security.*;
|
||||
// the file.
|
||||
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) {
|
||||
|
||||
// Use System.out.println to print lines
|
||||
// Use System.out.println() to print lines.
|
||||
System.out.println("Hello World!");
|
||||
System.out.println(
|
||||
"Integer: " + 10 +
|
||||
" Double: " + 3.14 +
|
||||
" 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("World");
|
||||
|
||||
@ -69,7 +69,7 @@ public class LearnJava {
|
||||
// L is used to denote that this variable value is of type Long;
|
||||
// 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 fooFloat = 234.5f;
|
||||
@ -86,7 +86,7 @@ public class LearnJava {
|
||||
// Char - A single 16-bit Unicode character
|
||||
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;
|
||||
|
||||
// Strings
|
||||
@ -101,10 +101,10 @@ public class LearnJava {
|
||||
System.out.println(bazString);
|
||||
|
||||
// Arrays
|
||||
//The array size must be decided upon instantiation
|
||||
//The following formats work for declaring an array
|
||||
//<datatype>[] <var name> = new <datatype>[<array size>];
|
||||
//<datatype> <var name>[] = new <datatype>[<array size>];
|
||||
// The array size must be decided upon instantiation
|
||||
// The following formats work for declaring an array
|
||||
// <datatype>[] <var name> = new <datatype>[<array size>];
|
||||
// <datatype> <var name>[] = new <datatype>[<array size>];
|
||||
int[] intArray = new int[10];
|
||||
String[] stringArray = new String[1];
|
||||
boolean boolArray[] = new boolean[100];
|
||||
@ -122,17 +122,17 @@ public class LearnJava {
|
||||
System.out.println("intArray @ 1: " + intArray[1]); // => 1
|
||||
|
||||
// Others to check out
|
||||
// ArrayLists - Like arrays except more functionality is offered,
|
||||
// and the size is mutable
|
||||
// ArrayLists - Like arrays except more functionality is offered, and
|
||||
// the size is mutable.
|
||||
// LinkedLists - Implementation of doubly-linked list. All of the
|
||||
// operations perform as could be expected for
|
||||
// a doubly-linked list.
|
||||
// Maps - A set of objects that maps keys to values. A map cannot contain
|
||||
// duplicate keys; each key can map to at most one value.
|
||||
// HashMaps - This class uses a hashtable to implement the Map interface.
|
||||
// This allows the execution time of basic operations,
|
||||
// such as get and insert element, to remain constant even
|
||||
// for large sets.
|
||||
// operations perform as could be expected for a
|
||||
// doubly-linked list.
|
||||
// Maps - A set of objects that maps keys to values. A map cannot
|
||||
// contain duplicate keys; each key can map to at most one value.
|
||||
// HashMaps - This class uses a hashtable to implement the Map
|
||||
// interface. This allows the execution time of basic
|
||||
// operations, such as get and insert element, to remain
|
||||
// constant even for large sets.
|
||||
|
||||
///////////////////////////////////////
|
||||
// Operators
|
||||
@ -160,13 +160,13 @@ public class LearnJava {
|
||||
|
||||
// Bitwise operators!
|
||||
/*
|
||||
~ Unary bitwise complement
|
||||
<< Signed left shift
|
||||
>> Signed right shift
|
||||
>>> Unsigned right shift
|
||||
& Bitwise AND
|
||||
^ Bitwise exclusive OR
|
||||
| Bitwise inclusive OR
|
||||
~ Unary bitwise complement
|
||||
<< Signed left shift
|
||||
>> Signed right shift
|
||||
>>> Unsigned right shift
|
||||
& Bitwise AND
|
||||
^ Bitwise exclusive OR
|
||||
| Bitwise inclusive OR
|
||||
*/
|
||||
|
||||
// Incrementations
|
||||
@ -175,10 +175,10 @@ public class LearnJava {
|
||||
// The ++ and -- operators increment and decrement by 1 respectively.
|
||||
// If they are placed before the variable, they increment then return;
|
||||
// after the variable they return then 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 = 1, prints 2 (post-decrement)
|
||||
System.out.println(--i); //i = 0, prints 0 (pre-decrement)
|
||||
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 = 1, prints 2 (post-decrement)
|
||||
System.out.println(--i); // i = 0, prints 0 (pre-decrement)
|
||||
|
||||
///////////////////////////////////////
|
||||
// Control Structures
|
||||
@ -197,73 +197,69 @@ public class LearnJava {
|
||||
|
||||
// While loop
|
||||
int fooWhile = 0;
|
||||
while(fooWhile < 100)
|
||||
{
|
||||
//System.out.println(fooWhile);
|
||||
//Increment the counter
|
||||
//Iterated 100 times, fooWhile 0,1,2...99
|
||||
while(fooWhile < 100) {
|
||||
System.out.println(fooWhile);
|
||||
// Increment the counter
|
||||
// Iterated 100 times, fooWhile 0,1,2...99
|
||||
fooWhile++;
|
||||
}
|
||||
System.out.println("fooWhile Value: " + fooWhile);
|
||||
|
||||
// Do While Loop
|
||||
int fooDoWhile = 0;
|
||||
do
|
||||
{
|
||||
//System.out.println(fooDoWhile);
|
||||
//Increment the counter
|
||||
//Iterated 99 times, fooDoWhile 0->99
|
||||
do {
|
||||
System.out.println(fooDoWhile);
|
||||
// Increment the counter
|
||||
// Iterated 99 times, fooDoWhile 0->99
|
||||
fooDoWhile++;
|
||||
}while(fooDoWhile < 100);
|
||||
} while(fooDoWhile < 100);
|
||||
System.out.println("fooDoWhile Value: " + fooDoWhile);
|
||||
|
||||
// For Loop
|
||||
int fooFor;
|
||||
//for loop structure => for(<start_statement>; <conditional>; <step>)
|
||||
for(fooFor=0; fooFor<10; fooFor++){
|
||||
//System.out.println(fooFor);
|
||||
//Iterated 10 times, fooFor 0->9
|
||||
// for loop structure => for(<start_statement>; <conditional>; <step>)
|
||||
for (fooFor = 0; fooFor < 10; fooFor++) {
|
||||
System.out.println(fooFor);
|
||||
// Iterated 10 times, fooFor 0->9
|
||||
}
|
||||
System.out.println("fooFor Value: " + fooFor);
|
||||
|
||||
// For Each Loop
|
||||
// An automatic iteration through an array or list of objects.
|
||||
int[] fooList = {1,2,3,4,5,6,7,8,9};
|
||||
//for each loop structure => for(<object> : <array_object>)
|
||||
//reads as: for each object in the array
|
||||
//note: the object type must match the array.
|
||||
// The for loop is also able to iterate over arrays as well as objects
|
||||
// that implement the Iterable interface.
|
||||
int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
// for each loop structure => for (<object> : <iterable>)
|
||||
// reads as: for each element in the iterable
|
||||
// note: the object type must match the element type of the iterable.
|
||||
|
||||
for( int bar : fooList ){
|
||||
//System.out.println(bar);
|
||||
for (int bar : fooList) {
|
||||
System.out.println(bar);
|
||||
//Iterates 9 times and prints 1-9 on new lines
|
||||
}
|
||||
|
||||
// Switch Case
|
||||
// A switch works with the byte, short, char, and int data types.
|
||||
// It also works with enumerated types (discussed in Enum Types),
|
||||
// the String class, and a few special classes that wrap
|
||||
// primitive types: Character, Byte, Short, and Integer.
|
||||
// It also works with enumerated types (discussed in Enum Types), the
|
||||
// String class, and a few special classes that wrap primitive types:
|
||||
// Character, Byte, Short, and Integer.
|
||||
int month = 3;
|
||||
String monthString;
|
||||
switch (month){
|
||||
case 1:
|
||||
monthString = "January";
|
||||
switch (month) {
|
||||
case 1: monthString = "January";
|
||||
break;
|
||||
case 2:
|
||||
monthString = "February";
|
||||
case 2: monthString = "February";
|
||||
break;
|
||||
case 3:
|
||||
monthString = "March";
|
||||
break;
|
||||
default:
|
||||
monthString = "Some other month";
|
||||
case 3: monthString = "March";
|
||||
break;
|
||||
default: monthString = "Some other month";
|
||||
break;
|
||||
}
|
||||
System.out.println("Switch Case Result: " + monthString);
|
||||
|
||||
// Conditional Shorthand
|
||||
// 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;
|
||||
String bar = (foo < 10) ? "A" : "B";
|
||||
System.out.println(bar); // Prints A, because the statement is true
|
||||
@ -287,9 +283,8 @@ public class LearnJava {
|
||||
// String
|
||||
|
||||
// Typecasting
|
||||
// You can also cast java objects, there's a lot of details and
|
||||
// deals with some more intermediate concepts.
|
||||
// Feel free to check it out here:
|
||||
// You can also cast Java objects, there's a lot of details and deals
|
||||
// with some more intermediate concepts. Feel free to check it out here:
|
||||
// http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
|
||||
|
||||
|
||||
@ -319,9 +314,9 @@ public class LearnJava {
|
||||
|
||||
|
||||
// Class Declaration Syntax:
|
||||
// <public/private/protected> class <class name>{
|
||||
// //data fields, constructors, functions all inside.
|
||||
// //functions are called as methods in Java.
|
||||
// <public/private/protected> class <class name> {
|
||||
// // data fields, constructors, functions all inside.
|
||||
// // functions are called as methods in Java.
|
||||
// }
|
||||
|
||||
class Bicycle {
|
||||
@ -342,7 +337,8 @@ class Bicycle {
|
||||
}
|
||||
|
||||
// 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.cadence = startCadence;
|
||||
this.speed = startSpeed;
|
||||
@ -388,10 +384,8 @@ class Bicycle {
|
||||
//Method to display the attribute values of this Object.
|
||||
@Override
|
||||
public String toString() {
|
||||
return "gear: " + gear +
|
||||
" cadence: " + cadence +
|
||||
" speed: " + speed +
|
||||
" name: " + name;
|
||||
return "gear: " + gear + " cadence: " + cadence + " speed: " + speed +
|
||||
" name: " + name;
|
||||
}
|
||||
} // end class Bicycle
|
||||
|
||||
@ -405,26 +399,26 @@ class PennyFarthing extends Bicycle {
|
||||
super(startCadence, startSpeed, 0, "PennyFarthing");
|
||||
}
|
||||
|
||||
// You should mark a method you're overriding with an @annotation
|
||||
// To learn more about what annotations are and their purpose
|
||||
// check this out: http://docs.oracle.com/javase/tutorial/java/annotations/
|
||||
// You should mark a method you're overriding with an @annotation.
|
||||
// To learn more about what annotations are and their purpose check this
|
||||
// out: http://docs.oracle.com/javase/tutorial/java/annotations/
|
||||
@Override
|
||||
public void setGear(int gear) {
|
||||
gear = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Interfaces
|
||||
//Interface declaration syntax
|
||||
//<access-level> interface <interface-name> extends <super-interfaces> {
|
||||
// //Constants
|
||||
// //Method declarations
|
||||
//}
|
||||
// Interfaces
|
||||
// Interface declaration syntax
|
||||
// <access-level> interface <interface-name> extends <super-interfaces> {
|
||||
// // Constants
|
||||
// // Method declarations
|
||||
// }
|
||||
|
||||
//Example - Food:
|
||||
// Example - Food:
|
||||
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 {
|
||||
@ -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 {
|
||||
@Override
|
||||
public void eat() {
|
||||
//...
|
||||
// ...
|
||||
}
|
||||
|
||||
@Override
|
||||
public void digest() {
|
||||
//...
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
//In java, you can extend only one class, but you can implement many interfaces.
|
||||
//For example:
|
||||
public class ExampleClass extends ExampleClassParent implements InterfaceOne, InterfaceTwo {
|
||||
// In Java, you can extend only one class, but you can implement many
|
||||
// interfaces. For example:
|
||||
public class ExampleClass extends ExampleClassParent implements InterfaceOne,
|
||||
InterfaceTwo {
|
||||
@Override
|
||||
public void InterfaceOneMethod() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void InterfaceTwoMethod() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 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)
|
||||
|
||||
* [Java The Complete Reference](http://www.amazon.com/gp/product/0071606300)
|
||||
|
||||
|
||||
|
@ -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.
|
||||
|
||||
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.
|
||||
|
||||
```json
|
||||
|
@ -8,7 +8,7 @@ filename: learnjulia.jl
|
||||
Julia is a new homoiconic functional language focused on technical computing.
|
||||
While having the full power of homoiconic macros, first-class functions, and low-level control, Julia is as easy to learn and use as Python.
|
||||
|
||||
This is based on the current development version of Julia, as of October 18th, 2013.
|
||||
This is based on Julia 0.3.
|
||||
|
||||
```ruby
|
||||
|
||||
@ -91,7 +91,7 @@ false
|
||||
|
||||
# $ can be used for string interpolation:
|
||||
"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.
|
||||
@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.
|
||||
|
||||
# You can initialize arrays from ranges
|
||||
a = [1:5] # => 5-element Int64 Array: [1,2,3,4,5]
|
||||
a = [1:5;] # => 5-element Int64 Array: [1,2,3,4,5]
|
||||
|
||||
# You can look at ranges with slice syntax.
|
||||
a[1:3] # => [1, 2, 3]
|
||||
@ -264,7 +264,7 @@ in(("two", 3), filled_dict) # => false
|
||||
haskey(filled_dict, "one") # => true
|
||||
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
|
||||
filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489
|
||||
catch e
|
||||
|
@ -155,7 +155,7 @@ var anotherArray = ["Default index", "starts at", "0"]
|
||||
|
||||
# More data structures are available, including tables, sets, lists, queues,
|
||||
# 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
|
||||
@ -174,7 +174,7 @@ else:
|
||||
|
||||
# `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!"
|
||||
let number: int = 42
|
||||
var
|
||||
@ -263,11 +263,11 @@ performance, and compile-time features.
|
||||
|
||||
## Further Reading
|
||||
|
||||
* [Home Page](http://nimrod-lang.org)
|
||||
* [Download](http://nimrod-lang.org/download.html)
|
||||
* [Community](http://nimrod-lang.org/community.html)
|
||||
* [FAQ](http://nimrod-lang.org/question.html)
|
||||
* [Documentation](http://nimrod-lang.org/documentation.html)
|
||||
* [Manual](http://nimrod-lang.org/manual.html)
|
||||
* [Standard Library](http://nimrod-lang.org/lib.html)
|
||||
* [Rosetta Code](http://rosettacode.org/wiki/Category:Nimrod)
|
||||
* [Home Page](http://nim-lang.org)
|
||||
* [Download](http://nim-lang.org/download.html)
|
||||
* [Community](http://nim-lang.org/community.html)
|
||||
* [FAQ](http://nim-lang.org/question.html)
|
||||
* [Documentation](http://nim-lang.org/documentation.html)
|
||||
* [Manual](http://nim-lang.org/docs/manual.html)
|
||||
* [Standard Library](http://nim-lang.org/docs/lib.html)
|
||||
* [Rosetta Code](http://rosettacode.org/wiki/Category:Nim)
|
||||
|
@ -47,9 +47,9 @@ my %fruit_color = ("apple", "red", "banana", "yellow");
|
||||
# You can use whitespace and the "=>" operator to lay them out more nicely:
|
||||
|
||||
my %fruit_color = (
|
||||
apple => "red",
|
||||
banana => "yellow",
|
||||
);
|
||||
apple => "red",
|
||||
banana => "yellow",
|
||||
);
|
||||
# Scalars, arrays and hashes are documented more fully in perldata.
|
||||
# (perldoc perldata).
|
||||
|
||||
@ -60,17 +60,17 @@ my %fruit_color = (
|
||||
|
||||
# Perl has most of the usual conditional and looping constructs.
|
||||
|
||||
if ( $var ) {
|
||||
...
|
||||
} elsif ( $var eq 'bar' ) {
|
||||
...
|
||||
if ($var) {
|
||||
...
|
||||
} elsif ($var eq 'bar') {
|
||||
...
|
||||
} else {
|
||||
...
|
||||
...
|
||||
}
|
||||
|
||||
unless ( condition ) {
|
||||
...
|
||||
}
|
||||
unless (condition) {
|
||||
...
|
||||
}
|
||||
# This is provided as a more readable version of "if (!condition)"
|
||||
|
||||
# the Perlish post-condition way
|
||||
@ -78,19 +78,29 @@ print "Yow!" if $zippy;
|
||||
print "We have no bananas" unless $bananas;
|
||||
|
||||
# while
|
||||
while ( condition ) {
|
||||
...
|
||||
}
|
||||
while (condition) {
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
# for and foreach
|
||||
for ($i = 0; $i <= $max; $i++) {
|
||||
...
|
||||
}
|
||||
# for loops and iteration
|
||||
for (my $i = 0; $i < $max; $i++) {
|
||||
print "index is $i";
|
||||
}
|
||||
|
||||
foreach (@array) {
|
||||
print "This element is $_\n";
|
||||
}
|
||||
for (my $i = 0; $i < @elements; $i++) {
|
||||
print "Current element is " . $elements[$i];
|
||||
}
|
||||
|
||||
for my $element (@elements) {
|
||||
print $element;
|
||||
}
|
||||
|
||||
# implicitly
|
||||
|
||||
for (@elements) {
|
||||
print;
|
||||
}
|
||||
|
||||
|
||||
#### Regular expressions
|
||||
@ -129,9 +139,11 @@ my @lines = <$in>;
|
||||
# Writing subroutines is easy:
|
||||
|
||||
sub logger {
|
||||
my $logmessage = shift;
|
||||
open my $logfile, ">>", "my.log" or die "Could not open my.log: $!";
|
||||
print $logfile $logmessage;
|
||||
my $logmessage = shift;
|
||||
|
||||
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:
|
||||
|
@ -213,7 +213,7 @@ say $x; #=> 52
|
||||
# - `if`
|
||||
# Before talking about `if`, we need to know which values are "Truthy"
|
||||
# (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.
|
||||
# Every other value is Truthy.
|
||||
if True {
|
||||
|
@ -60,7 +60,7 @@ $float = 1.2e3;
|
||||
$float = 7E-10;
|
||||
|
||||
// Delete variable
|
||||
unset($int1)
|
||||
unset($int1);
|
||||
|
||||
// Arithmetic
|
||||
$sum = 1 + 1; // 2
|
||||
|
637
pl-pl/python-pl.html.markdown
Normal file
637
pl-pl/python-pl.html.markdown
Normal 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)
|
||||
|
@ -9,7 +9,7 @@ translators:
|
||||
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
|
||||
|
||||
@ -236,7 +236,7 @@ for ( e in map ) {
|
||||
|
||||
Sobrecarregamento de Operadores para uma lsita dos operadores comuns que
|
||||
Grooby suporta:
|
||||
http://groovy.codehaus.org/Operator+Overloading
|
||||
http://www.groovy-lang.org/operators.html#Operator-Overloading
|
||||
|
||||
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 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:
|
||||
def clos = { println "Hello World!" }
|
||||
@ -413,11 +413,11 @@ assert soma(2,5) == 7
|
||||
|
||||
## 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/)
|
||||
|
||||
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
|
||||
|
||||
|
@ -46,7 +46,7 @@ to Python 2.x. For Python 3.x, take a look at the [Python 3 tutorial](http://lea
|
||||
2.0 # This is a float
|
||||
11.0 / 4.0 # => 2.75 ahhh...much better
|
||||
|
||||
# Result of integer division truncated down both for positive and negative.
|
||||
# Result of integer division truncated down both for positive and negative.
|
||||
5 // 3 # => 1
|
||||
5.0 // 3.0 # => 1.0 # works on floats too
|
||||
-5 // 3 # => -2
|
||||
@ -191,14 +191,14 @@ li[2:] # => [4, 3]
|
||||
li[:3] # => [1, 2, 4]
|
||||
# Select every second entry
|
||||
li[::2] # =>[1, 4]
|
||||
# Revert the list
|
||||
# Reverse a copy of the list
|
||||
li[::-1] # => [3, 4, 2, 1]
|
||||
# Use any combination of these to make advanced slices
|
||||
# li[start:end:step]
|
||||
|
||||
# Remove arbitrary elements from a list with "del"
|
||||
del li[2] # li is now [1, 2, 3]
|
||||
|
||||
r
|
||||
# You can add lists
|
||||
li + other_li # => [1, 2, 3, 4, 5, 6]
|
||||
# Note: values for li and for other_li are not modified.
|
||||
@ -439,14 +439,14 @@ def pass_all_the_args(*args, **kwargs):
|
||||
print varargs(*args)
|
||||
print keyword_args(**kwargs)
|
||||
|
||||
# Function Scope
|
||||
# Function Scope
|
||||
x = 5
|
||||
|
||||
def setX(num):
|
||||
# Local var x not the same as global variable x
|
||||
x = num # => 43
|
||||
print x # => 43
|
||||
|
||||
|
||||
def setGlobalX(num):
|
||||
global x
|
||||
print x # => 5
|
||||
|
@ -39,7 +39,7 @@ Note: This article applies to Python 3 specifically. Check out [here](http://lea
|
||||
# Except division which returns floats by default
|
||||
35 / 5 # => 7.0
|
||||
|
||||
# Result of integer division truncated down both for positive and negative.
|
||||
# Result of integer division truncated down both for positive and negative.
|
||||
5 // 3 # => 1
|
||||
5.0 // 3.0 # => 1.0 # works on floats too
|
||||
-5 // 3 # => -2
|
||||
@ -73,8 +73,8 @@ False or True #=> True
|
||||
# Note using Bool operators with ints
|
||||
0 and 2 #=> 0
|
||||
-5 or 0 #=> -5
|
||||
0 == False #=> True
|
||||
2 == True #=> False
|
||||
0 == False #=> True
|
||||
2 == True #=> False
|
||||
1 == True #=> True
|
||||
|
||||
# Equality is ==
|
||||
@ -145,7 +145,7 @@ bool({}) #=> False
|
||||
# Python has a print function
|
||||
print("I'm Python. Nice to meet you!")
|
||||
|
||||
# No need to declare variables before assigning to them.
|
||||
# No need to declare variables before assigning to them.
|
||||
# Convention is to use lower_case_with_underscores
|
||||
some_var = 5
|
||||
some_var # => 5
|
||||
@ -186,7 +186,7 @@ li[2:] # => [4, 3]
|
||||
li[:3] # => [1, 2, 4]
|
||||
# Select every second entry
|
||||
li[::2] # =>[1, 4]
|
||||
# Revert the list
|
||||
# Return a reversed copy of the list
|
||||
li[::-1] # => [3, 4, 2, 1]
|
||||
# Use any combination of these to make advanced slices
|
||||
# li[start:end:step]
|
||||
@ -196,7 +196,7 @@ del li[2] # li is now [1, 2, 3]
|
||||
|
||||
# You can add lists
|
||||
# Note: values for li and for other_li are not modified.
|
||||
li + other_li # => [1, 2, 3, 4, 5, 6]
|
||||
li + other_li # => [1, 2, 3, 4, 5, 6]
|
||||
|
||||
# Concatenate lists with "extend()"
|
||||
li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
|
||||
@ -213,7 +213,7 @@ tup = (1, 2, 3)
|
||||
tup[0] # => 1
|
||||
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
|
||||
tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
|
||||
tup[:2] # => (1, 2)
|
||||
@ -235,15 +235,15 @@ filled_dict = {"one": 1, "two": 2, "three": 3}
|
||||
# Look up values with []
|
||||
filled_dict["one"] # => 1
|
||||
|
||||
# Get all keys as a list with "keys()".
|
||||
# We need to wrap the call in list() because we are getting back an iterable. We'll talk about those later.
|
||||
# Note - Dictionary key ordering is not guaranteed.
|
||||
# Your results might not match this exactly.
|
||||
# Get all keys as an iterable with "keys()". We need to wrap the call in list()
|
||||
# to turn it into a list. We'll talk about those later. Note - Dictionary key
|
||||
# ordering is not guaranteed. Your results might not match this exactly.
|
||||
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.
|
||||
# Note - Same as above regarding key ordering.
|
||||
# Get all values as an iterable with "values()". Once again we need to wrap it
|
||||
# in list() to get it out of the iterable. Note - Same as above regarding key
|
||||
# ordering.
|
||||
list(filled_dict.values()) # => [3, 2, 1]
|
||||
|
||||
|
||||
@ -281,7 +281,7 @@ some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4}
|
||||
# Can set new variables to a set
|
||||
filled_set = some_set
|
||||
|
||||
# Add one more item to the set
|
||||
# Add one more item to the set
|
||||
filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
|
||||
|
||||
# Do set intersection with &
|
||||
@ -328,7 +328,7 @@ for animal in ["dog", "cat", "mouse"]:
|
||||
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
|
||||
prints:
|
||||
0
|
||||
@ -340,7 +340,7 @@ for i in range(4):
|
||||
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
|
||||
prints:
|
||||
4
|
||||
@ -458,14 +458,14 @@ all_the_args(**kwargs) # equivalent to foo(a=3, b=4)
|
||||
all_the_args(*args, **kwargs) # equivalent to foo(1, 2, 3, 4, a=3, b=4)
|
||||
|
||||
|
||||
# Function Scope
|
||||
# Function Scope
|
||||
x = 5
|
||||
|
||||
def setX(num):
|
||||
# Local var x not the same as global variable x
|
||||
x = num # => 43
|
||||
print (x) # => 43
|
||||
|
||||
|
||||
def setGlobalX(num):
|
||||
global x
|
||||
print (x) # => 5
|
||||
@ -512,8 +512,8 @@ class Human(object):
|
||||
# Basic initializer, this is called when this class is instantiated.
|
||||
# Note that the double leading and trailing underscores denote objects
|
||||
# or attributes that are used by python but that live in user-controlled
|
||||
# namespaces. Methods(or objects or attributes) like: __init__, __str__,
|
||||
# __repr__ etc. are called magic methods (or sometimes called dunder methods)
|
||||
# namespaces. Methods(or objects or attributes) like: __init__, __str__,
|
||||
# __repr__ etc. are called magic methods (or sometimes called dunder methods)
|
||||
# You should not invent such names on your own.
|
||||
def __init__(self, name):
|
||||
# Assign the argument to the instance's name attribute
|
||||
@ -600,7 +600,7 @@ def double_numbers(iterable):
|
||||
# double_numbers.
|
||||
# Note range is a generator too. Creating a list 1-900000000 would take lot of
|
||||
# time to be made
|
||||
# We use a trailing underscore in variable names when we want to use a name that
|
||||
# We use a trailing underscore in variable names when we want to use a name that
|
||||
# would normally collide with a python keyword
|
||||
range_ = range(1, 900000000)
|
||||
# will double all numbers until a result >=30 found
|
||||
|
284
ru-ru/bash-ru.html.markdown
Normal file
284
ru-ru/bash-ru.html.markdown
Normal 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
|
||||
```
|
@ -79,10 +79,14 @@ true && false #=> false
|
||||
true || false #=> true
|
||||
!true #=> false
|
||||
|
||||
# Alternate spellings of logical operators
|
||||
true and false #=> false
|
||||
true or false #=> true
|
||||
not true #=> false
|
||||
# There are alternate versions of the logical operators with much lower
|
||||
# precedence. These are meant to be used as flow-control constructs to chain
|
||||
# statements together until one of them returns true or 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
|
||||
|
@ -5,15 +5,22 @@ contributors:
|
||||
filename: learnrust.rs
|
||||
---
|
||||
|
||||
Rust is an in-development programming language developed by Mozilla Research.
|
||||
It is relatively unique among systems languages in that it can assert memory
|
||||
safety *at compile time* without resorting to garbage collection. Rust’s first
|
||||
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
|
||||
nightly builds. On January 9 2015, Rust 1.0 Alpha was released, and the rate of
|
||||
changes to the Rust compiler that break existing code has dropped significantly
|
||||
since. However, a complete guarantee of backward compatibility will not exist
|
||||
until the final 1.0 release.
|
||||
Rust is a programming language developed by Mozilla Research.
|
||||
Rust combines low-level control over performance with high-level convenience and
|
||||
safety guarantees.
|
||||
|
||||
It achieves these goals without requiring a garbage collector or runtime, making
|
||||
it possible to use Rust libraries as a "drop-in replacement" for C.
|
||||
|
||||
Rust’s first release, 0.1, occurred in January 2012, and for 3 years development
|
||||
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
|
||||
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 doesn’t
|
||||
// actually contain the contents of a string, just a pointer to
|
||||
// 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
|
||||
|
||||
@ -92,7 +99,7 @@ fn main() {
|
||||
|
||||
// A slice – an immutable view into a vector or array
|
||||
// This is much like a string slice, but for vectors
|
||||
let slice: &[i32] = &*vector;
|
||||
let slice: &[i32] = &vector;
|
||||
|
||||
// Use `{:?}` to print something debug-style
|
||||
println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
|
||||
|
@ -3,13 +3,15 @@ language: "Standard ML"
|
||||
contributors:
|
||||
- ["Simon Shine", "http://shine.eu.org/"]
|
||||
- ["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
|
||||
side-effects. Some of the hard parts of learning Standard ML are: Recursion,
|
||||
pattern matching, type inference (guessing the right types but never allowing
|
||||
implicit type conversion). If you have an imperative background, not being able
|
||||
to update variables can feel severely inhibiting.
|
||||
implicit type conversion). Standard ML is distinguished from Haskell by including
|
||||
references, allowing variables to be updated.
|
||||
|
||||
```ocaml
|
||||
(* Comments in Standard ML begin with (* and end with *). Comments can be
|
||||
@ -135,9 +137,29 @@ val mixup = [ ("Alice", 39),
|
||||
|
||||
val good_bad_stuff =
|
||||
(["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! *)
|
||||
fun add_them (a, b) = a + b (* A simple function that adds two numbers *)
|
||||
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 n = fibonacci (n - 1) + fibonacci (n - 2) (* Recursive case *)
|
||||
|
||||
(* Pattern matching is also possible on composite types like tuples and lists.
|
||||
Writing "fun solve2 (a, b, c) = ..." is in fact a pattern match on the one
|
||||
three-tuple solve2 takes as argument. Similarly, but less intuitively, you
|
||||
can match on a list consisting of elements in it (from the beginning of the
|
||||
list only). *)
|
||||
(* Pattern matching is also possible on composite types like tuples, lists and
|
||||
records. Writing "fun solve2 (a, b, c) = ..." is in fact a pattern match on
|
||||
the one three-tuple solve2 takes as argument. Similarly, but less intuitively,
|
||||
you can match on a list consisting of elements in it (from the beginning of
|
||||
the list only). *)
|
||||
fun first_elem (x::xs) = x
|
||||
fun second_elem (x::y::xs) = y
|
||||
fun evenly_positioned_elems (odd::even::xs) = even::evenly_positioned_elems xs
|
||||
| evenly_positioned_elems [odd] = [] (* Base case: throw away *)
|
||||
| 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.
|
||||
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.",
|
||||
"I have a gun.",
|
||||
"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
|
||||
|
@ -159,7 +159,7 @@ Module Module1
|
||||
Console.Write(a.ToString() + " - " + b.ToString())
|
||||
Console.WriteLine(" = " + e.ToString.PadLeft(3))
|
||||
Console.Write(a.ToString() + " / " + b.ToString())
|
||||
Console.WriteLine(" = " + e.ToString.PadLeft(3))
|
||||
Console.WriteLine(" = " + f.ToString.PadLeft(3))
|
||||
Console.ReadLine()
|
||||
|
||||
End Sub
|
||||
@ -189,7 +189,7 @@ Module Module1
|
||||
Console.Write(a.ToString() + " - " + b.ToString())
|
||||
Console.WriteLine(" = " + e.ToString.PadLeft(3))
|
||||
Console.Write(a.ToString() + " / " + b.ToString())
|
||||
Console.WriteLine(" = " + e.ToString.PadLeft(3))
|
||||
Console.WriteLine(" = " + f.ToString.PadLeft(3))
|
||||
Console.ReadLine()
|
||||
'Ask the question, does the user wish to continue? Unfortunately it
|
||||
'is case sensitive.
|
||||
|
@ -5,7 +5,14 @@ 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:
|
||||
- ["Jinchang Ye", "https://github.com/Alwayswithme"]
|
||||
- ["Chunyang Xu", "https://github.com/XuChunyang"]
|
||||
filename: LearnBash-cn.sh
|
||||
lang: zh-cn
|
||||
@ -23,31 +30,45 @@ Bash 是一个为 GNU 计划编写的 Unix shell,是 Linux 和 Mac OS X 下的
|
||||
# 如你所见,注释以 # 开头,shebang 也是注释。
|
||||
|
||||
# 显示 “Hello world!”
|
||||
echo Hello, world!
|
||||
echo Hello world!
|
||||
|
||||
# 每一句指令以换行或分号隔开:
|
||||
echo 'This is the first line'; echo 'This is the second line'
|
||||
|
||||
# 声明一个变量:
|
||||
VARIABLE="Some string"
|
||||
Variable="Some string"
|
||||
|
||||
# 下面是错误的做法:
|
||||
VARIABLE = "Some string"
|
||||
# Bash 会把 VARIABLE 当做一个指令,由于找不到该指令,因此这里会报错。
|
||||
Variable = "Some string"
|
||||
# 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),或者以其他方式使用变量时,变量名前不加 $。
|
||||
# 如果要使用变量的值, 则要加 $。
|
||||
# 注意: ' (单引号) 不会展开变量(即会屏蔽掉变量)。
|
||||
|
||||
|
||||
# 在变量内部进行字符串代换
|
||||
echo ${VARIABLE/Some/A}
|
||||
# 会把 VARIABLE 中首次出现的 "some" 替换成 “A”。
|
||||
echo ${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 "Number of 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?"
|
||||
read NAME # 这里不需要声明新变量
|
||||
echo Hello, $NAME!
|
||||
read Name # 这里不需要声明新变量
|
||||
echo Hello, $Name!
|
||||
|
||||
# 通常的 if 结构看起来像这样:
|
||||
# 'man test' 可查看更多的信息
|
||||
if [ $NAME -ne $USER ]
|
||||
if [ $Name -ne $USER ]
|
||||
then
|
||||
echo "Your name is you username"
|
||||
echo "Your name isn't your username"
|
||||
else
|
||||
echo "Your name isn't you username"
|
||||
echo "Your name is your username"
|
||||
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"
|
||||
|
||||
# 在 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 ))
|
||||
|
||||
@ -88,18 +120,54 @@ ls -l # 列出文件和目录的详细信息
|
||||
# 用下面的指令列出当前目录下所有的 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"
|
||||
python2 hello.py > "output.out"
|
||||
python2 hello.py 2> "error.err"
|
||||
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.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."
|
||||
|
||||
# Bash 的 case 语句与 Java 和 C++ 中的 switch 语句类似:
|
||||
case "$VARIABLE" in
|
||||
case "$Variable" in
|
||||
# 列出需要匹配的字符串
|
||||
0) echo "There is a zero.";;
|
||||
1) echo "There is a one.";;
|
||||
@ -107,11 +175,37 @@ case "$VARIABLE" in
|
||||
esac
|
||||
|
||||
# 循环遍历给定的参数序列:
|
||||
# 变量$VARIABLE 的值会被打印 3 次。
|
||||
# 注意 ` ` 和 $( ) 等价。seq 返回长度为 3 的数组。
|
||||
for VARIABLE in `seq 3`
|
||||
# 变量$Variable 的值会被打印 3 次。
|
||||
for Variable in {1..3}
|
||||
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
|
||||
|
||||
# 你也可以使用函数
|
||||
@ -132,17 +226,52 @@ bar ()
|
||||
}
|
||||
|
||||
# 调用函数
|
||||
foo "My name is" $NAME
|
||||
foo "My name is" $Name
|
||||
|
||||
# 有很多有用的指令需要学习:
|
||||
tail -n 10 file.txt
|
||||
# 打印 file.txt 的最后 10 行
|
||||
head -n 10 file.txt
|
||||
tail -n 10 file.txt
|
||||
# 打印 file.txt 的前 10 行
|
||||
sort file.txt
|
||||
head -n 10 file.txt
|
||||
# 将 file.txt 按行排序
|
||||
uniq -d file.txt
|
||||
sort file.txt
|
||||
# 报告或忽略重复的行,用选项 -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
|
||||
```
|
||||
|
420
zh-cn/groovy-cn.html.markdown
Normal file
420
zh-cn/groovy-cn.html.markdown
Normal 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
|
||||
|
||||
|
||||
|
@ -341,7 +341,7 @@ var myFunc = myObj.myFunc;
|
||||
myFunc(); // = undefined
|
||||
|
||||
// 相应的,一个函数也可以被指定为一个对象的方法,并且可以通过`this`访问
|
||||
// 这个对象的成员,即使在行数被定义时并没有依附在对象上。
|
||||
// 这个对象的成员,即使在函数被定义时并没有依附在对象上。
|
||||
var myOtherFunc = function(){
|
||||
return this.myString.toUpperCase();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user