summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--bash.html.markdown7
-rw-r--r--c++.html.markdown349
-rw-r--r--c.html.markdown12
-rw-r--r--erlang.html.markdown14
-rw-r--r--learntmux.html.markdown71
-rw-r--r--markdown.html.markdown8
-rw-r--r--ocaml.html.markdown311
-rw-r--r--python.html.markdown14
-rw-r--r--python3.html.markdown32
-rw-r--r--ru-ru/python-ru.html.markdown266
-rw-r--r--tmux.html.markdown244
-rw-r--r--zh-cn/lua-cn.html.markdown1
-rw-r--r--zh-cn/markdown-cn.html.markdown2
13 files changed, 1157 insertions, 174 deletions
diff --git a/bash.html.markdown b/bash.html.markdown
index 57fb5c55..dc7d32b6 100644
--- a/bash.html.markdown
+++ b/bash.html.markdown
@@ -8,6 +8,7 @@ contributors:
- ["Denis Arh", "https://github.com/darh"]
- ["akirahirose", "https://twitter.com/akirahirose"]
- ["Anton Strömkvist", "http://lutic.org/"]
+ - ["Rahil Momin", "https://github.com/iamrahil"]
filename: LearnBash.sh
---
@@ -140,6 +141,12 @@ do
echo "$VARIABLE"
done
+# Or write it the "traditional for loop" way:
+for ((a=1; a <= 3; a++))
+do
+ echo $a
+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
diff --git a/c++.html.markdown b/c++.html.markdown
new file mode 100644
index 00000000..8cf72e47
--- /dev/null
+++ b/c++.html.markdown
@@ -0,0 +1,349 @@
+---
+language: c++
+filename: learncpp.cpp
+contributors:
+ - ["Steven Basart", "http://github.com/xksteven"]
+lang: en
+---
+
+I am writing this to highlight the differences and
+additions that C++ has with respect to C. My
+suggestion would be to follow the C tutorial first
+then look here for the additions and differences.
+
+```c++
+///////////////////////////////////////
+// C++ differences
+///////////////////////////////////////
+
+
+//In C++
+//cannot use void main()
+int main() { //or int main(int argc, char **argv)
+ //cannot end with return;
+ return 0;
+ //Can also end without return statement
+}
+
+//In C++
+/*
+ //This could lead to compiler errors and is discouraged
+ //#if 0 #endif pairs are encouraged instead
+*/
+
+//In C++
+sizeof(10) //Typically 4
+sizeof('c') == 1
+
+//In C
+sizeof('c') == sizeof(10) //true chars are passed as ints
+
+
+//In C++ strict prototyping
+void func(); //function which accepts no arguments
+
+//In C
+void func(); //function which may accept arguments
+
+
+//In C++
+for(int i = 0; i < 10; i++) {;}
+//In C must int i must be declared before
+
+
+//C++ Supports Function overloading
+//Provided each function takes different
+//parameters
+
+void printing(char const *myString)
+{printf("String %s\n",myString);} //Hello
+
+void printing(int myInt)
+{printf("My int is %d",myInt);} //15
+
+int main ()
+{
+ printing("Hello");
+ printing(15);
+}
+
+
+
+//C++ Default Function Arguments
+void two_ints(int a = 1, int b = 4);
+
+int main()
+{
+ two_ints(); // arguments: 1, 4
+ two_ints(20); // arguments: 20, 4
+ two_ints(20, 5); // arguments: 20, 5
+}
+
+
+//C++ added the nullptr which is different from 0
+int *ip = nullptr; // OK
+int value = nullptr; // error: value is no pointer
+
+
+///////////////////////////////////////
+// C++ Additions ontop of C
+///////////////////////////////////////
+
+
+///////////////////////////////////////
+// C++ Namespace
+///////////////////////////////////////
+
+//Namespaces allow you to define your own
+//functions and variables for use
+
+// Use '::' to change variable (or function) scope
+// Putting '::' before a function or variable will
+// reference a global scope
+
+// This allows you to make normal c library calls
+// std is for standard library
+using namespace std;
+
+#include <stdio.h>
+
+int counter = 50; // global variable
+
+int main()
+{
+ for (int counter = 1; // this refers to the
+ counter < 2; // local variable
+ counter++)
+ {
+ printf("Global var %d local var %d\n",
+ ::counter, // global variable
+ counter); // local variable
+ // => Global var 50 local var 1
+ }
+}
+
+// Namespaces can be nested
+
+
+namespace myFirstNameSpace
+{
+ namespace myInnerSoul
+ {
+ cos(int x)
+ {
+ printf("My inner soul was made to program.");
+ }
+ }
+}
+
+namespace anotherNameSpace
+{
+ cos(int x) {;} //does nothing
+}
+
+int main()
+{
+ //Specify the full path because main is outside of both namespaces.
+ //Will print out My inner soul was made to program.
+ myFirstNameSpace::myInnerSoul::cos(60);
+}
+
+
+///////////////////////////////////////
+// C++ Strings
+///////////////////////////////////////
+
+//Strings in C++ are Objects and have many functions
+myString = "Hello";
+myOtherString = " World";
+
+myString + myOtherString; // => "Hello World"
+
+myString + ' You'; // => "Hello You"
+
+myString != myOtherString; //True
+
+//An example of a string method
+myString.append(" Dog"); // => "Hello Dog"
+
+
+///////////////////////////////////////
+// C++ Input Output
+///////////////////////////////////////
+
+//C++ input and output streams
+//cin, cout, cerr, << is insertion and >> is extraction operator
+#include <iostream>
+
+using namespace std;
+
+int main()
+{
+
+ int myInt;
+
+ //Prints to stdout (or terminal/screen)
+ cout << "Enter your fav number:\n"
+ //Takes in input
+ cin >> myInt;
+
+ //cout can also be formatted
+ cout << "Your fav number is " << myInt << "\n"
+ //Your fav number is ##
+
+ cerr << "Used for error messages"
+}
+
+
+///////////////////////////////////////
+// C++ Classes
+///////////////////////////////////////
+
+
+//First example of classes
+#include <iostream>
+
+//define a class
+class Doggie
+{
+ std::string name;
+ int weight;
+
+ // These are only the declarations
+ //Can also have private and protected
+ public:
+ //The public methods (can also include variables)
+
+ // Default constructor
+ Doggie();
+
+ void setName(std::string dogsName);
+ void setWeight(int dogsWeight);
+ void printDog();
+
+ //Can define functions within class declaration too
+ void dogBark() {std::cout << "Bark Bark\n"}
+
+ //Destructors are methods that free the allocated space
+ ~doggieDestructor();
+ //if no destructor compiler defines the trivial destructor
+
+//Classes are similar to structs and must close the } with ;
+};
+
+// This is the implementation of the class methods
+// Also called the definition
+void Doggie::Doggie () {
+ std::cout << "A doggie is born. Woof!\n";
+}
+
+void Doggie::setName (std::string doggie_name) {
+ name = doggie_name;
+}
+
+void Doggie::setWeight (int doggie_weight) {
+ weight = doggie_weight;
+}
+
+void Doggie::printDog () {
+ std::cout << "Dog is " << name << " weighs" << weight << "\n";
+}
+
+void Doggie::~doggieDestructor () {
+ delete[] name;
+ delete weight;
+}
+
+int main () {
+ Doggie deedee; // prints out a doggie is born. Woof!
+ deedee.setName ("Barkley");
+ deedee.setWeight(1000000);
+ deedee.printDog;
+ //prints => Dog is Barkley weighs 1000000
+ return 0;
+}
+
+
+//C++ Class inheritance
+
+class German_Sheperd
+{
+ //This class now inherits everything public and protected from Doggie class
+ Doggie d_dog;
+
+ //Good practice to put d_ in front of datatypes in classes
+ std::string d_type;
+
+ public:
+ void dogType() {d_type = "German Sheperd";}
+};
+
+
+
+///////////////////////////////////////
+// C++ Exception Handling
+///////////////////////////////////////
+
+try {
+ throw 12.25; // throws a double no handler declared
+} catch (int errorNum)
+{
+ std::cout << "I caught an int " << errorNum << "\n";
+//default catcher
+} catch (...)
+{
+ std::cout << "I got an error. Not sure what but I can pass it up.";
+ throw;
+}
+
+
+///////////////////////////////////////
+// C++ Operator Overloading
+///////////////////////////////////////
+
+// In C++ you can overload operators such as +, -, new, etc.
+
+#include <iostream>
+using namespace std;
+
+class Vector {
+ public:
+ double x,y;
+ Vector () {};
+ Vector (double a, double b) : x(a), y(b) {}
+ Vector operator + (const CVector&);
+ Vector operator += (const CVector&);
+};
+
+Vector Vector::operator+ (const Vector& rhs)
+{
+ Vector temp;
+ temp.x = x + rhs.x;
+ temp.y = y + rhs.y;
+ return temp;
+}
+
+Vector Vector::operator+= (const Vector& rhs)
+{
+ x += rhs.x;
+ y += rhs.y;
+ return *this;
+}
+
+int main () {
+ Vector up (0,1);
+ Vector right (1,0);
+ Vector result;
+ // This calls the Vector + operator
+ // Vector up calls the + (function) with right as its paramater
+ result = up + right;
+ // prints out => Result is upright (1,1)
+ cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
+ return 0;
+}
+
+```
+Futher Reading
+
+for more resources see: http://www.icce.rug.nl/documents/cplusplus/
+for other reference material: http://www.cplusplus.com/doc/tutorial/
diff --git a/c.html.markdown b/c.html.markdown
index 79b7aec7..cbb6d289 100644
--- a/c.html.markdown
+++ b/c.html.markdown
@@ -4,6 +4,7 @@ filename: learnc.c
contributors:
- ["Adam Bard", "http://adambard.com/"]
- ["Árpád Goretity", "http://twitter.com/H2CO3_iOS"]
+ - ["Jakub Trzebiatowski", "http://cbs.stgn.pl"]
---
@@ -175,6 +176,9 @@ int main() {
i2 * i1; // => 2
i1 / i2; // => 0 (0.5, but truncated towards 0)
+ // You need to cast at least one integer to float to get a floating-point result
+ (float)i1 / i2 // => 0.5f
+ i1 / (double)i2 // => 0.5 // Same with double
f1 / f2; // => 0.5, plus or minus epsilon
// Floating-point numbers and calculations are not exact
@@ -194,9 +198,11 @@ int main() {
2 >= 2; // => 1
// C is not Python - comparisons don't chain.
- // WRONG:
- //int between_0_and_2 = 0 < a < 2;
- // Correct:
+ // Warning: The line below will compile, but it means `(0 < a) < 2`.
+ // This expression is always true, because (0 < a) could be either 1 or 0.
+ // In this case it's 1, because (0 < 1).
+ int between_0_and_2 = 0 < a < 2;
+ // Instead use:
int between_0_and_2 = 0 < a && a < 2;
// Logic works on ints
diff --git a/erlang.html.markdown b/erlang.html.markdown
index 64b62f05..04086aeb 100644
--- a/erlang.html.markdown
+++ b/erlang.html.markdown
@@ -260,22 +260,22 @@ spawn(F). % <0.44.0>
% For all of this to be useful we need to be able to receive messages. This is
% achieved with the `receive` mechanism:
--module(caculateGeometry).
+-module(calculateGeometry).
-compile(export_all).
-caculateAera() ->
+calculateArea() ->
receive
{rectangle, W, H} ->
W * H;
{circle, R} ->
3.14 * R * R;
_ ->
- io:format("We can only caculate area of rectangles or circles.")
+ io:format("We can only calculate area of rectangles or circles.")
end.
-% Compile the module and create a process that evaluates `caculateAera` in the shell
-c(caculateGeometry).
-CaculateAera = spawn(caculateGeometry, caculateAera, []).
-CaculateAera ! {circle, 2}. % 12.56000000000000049738
+% 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
self(). % <0.41.0>
diff --git a/learntmux.html.markdown b/learntmux.html.markdown
deleted file mode 100644
index eaf3fd25..00000000
--- a/learntmux.html.markdown
+++ /dev/null
@@ -1,71 +0,0 @@
----
-category: tool
-tool: tmux
-contributors:
- - ["kaernyk", "http://github.com/kaernyk"]
-filename: LearnTmux.txt
----
-
-
- tmux is a terminal multiplexer: it enables a number of terminals to be
-created, accessed, and controlled from a single screen. tmux may be detached
-from a screen and continue running in the background, then later reattached.
-
- Once you feel comfortable manipulating tmux to suit your needs, I strongly
-suggest you read the man pages.
-
-
-
-```
-# Session Management
-
- tmux new Create new session
- -s "Session" Create named session
- -n "Window" Create named Window
- -c "/dir" Start in target directory
-
- C^b $ Rename current session
- C^b d Detach current session
- C^b D Select session to detach
-
- tmux attach Attach last/available session
- -t "#" Attach target session
- -d Detach the session from other instances
-
- tmux ls List open sessions
- C^b s Select new session for attached client interactively
-
- kill-session Kill current session
- -t "#" Kill target session
- -a Kill all sessions
- -a -t "#" Kill all sessions but the target
-
-
-# Window Management
-
- C^b c Create another window
- C^b " Split Horizontally
- C^b % Split Vertically
- C^b M-(1-5) 1) Tile vertically
- 2) Tile horizontally
- 3) Tile Vertically /w large horizontal
- 4) Tile horizontally /w large vertical
- 5) Tile all windows evenly
-
- C^b q Briefly display pane indexes
- C^# Choose current window by #
- C^b w Choose current window interactively
- C^b n Change to next window
- C^b p Change to previous window
- C^b Up, Right Change to pane in selected direction
- Down, left
- C^b { Swap current/previous window
- C^b } Swap current/next window
-
- C^b C-Up, Right Resize in steps of one cell
- Down, left
- C^b M-Up, Right resize in steps of five cells
- Down, left
-
- exit or C^b x Kill the current window
-```
diff --git a/markdown.html.markdown b/markdown.html.markdown
index 805255b8..3d4d0af6 100644
--- a/markdown.html.markdown
+++ b/markdown.html.markdown
@@ -39,7 +39,7 @@ This is an h2
-------------
<!-- Simple text styles -->
-<!-- Text can be easily styled as italic, bold, or strikethrough using markdown -->
+<!-- Text can be easily styled as italic or bold using markdown -->
*This text is in italics.*
_And so is this text._
@@ -52,7 +52,7 @@ __And so is this text.__
*__And this!__*
<!-- In Github Flavored Markdown, which is used to render markdown files on
-Github, we also have: -->
+Github, we also have strikethrough: -->
~~This text is rendered with strikethrough.~~
@@ -201,11 +201,11 @@ can be anything so long as they are unique. -->
<!-- Images -->
<!-- Images are done the same way as links but with an exclamation point in front! -->
-![This is hover-text (alt text) for my image](http://imgur.com/myimage.jpg "An optional title")
+![This is the alt-attribute for my image](http://imgur.com/myimage.jpg "An optional title")
<!-- And reference style works as expected -->
-![This is the hover-text.][myimage]
+![This is the alt-attribute.][myimage]
[myimage]: relative/urls/cool/image.jpg "if you need a title, it's here"
diff --git a/ocaml.html.markdown b/ocaml.html.markdown
new file mode 100644
index 00000000..c104823a
--- /dev/null
+++ b/ocaml.html.markdown
@@ -0,0 +1,311 @@
+---
+language: OCaml
+contributors:
+ - ["Daniil Baturin", "http://baturin.org/"]
+---
+
+OCaml is a strictly evaluated functional language with some imperative
+features.
+
+Along with StandardML and its dialects it belongs to ML language family.
+Just like StandardML, there are both a compiler and an interpreter
+for OCaml. The interpreter binary is normally called "ocaml" and
+the compiler is "ocamlc.opt". There is also a bytecode compiler, "ocamlc",
+but there are few reasons to use it.
+
+It is strongly and statically typed, but instead of using manually written
+type annotations, it infers types of expressions using Hindley-Milner algorithm.
+It makes type annotations unnecessary in most cases, but can be a major
+source of confusion for beginners.
+
+When you are in the top level loop, OCaml will print the inferred type
+after you enter an expression.
+
+```
+# let inc x = x + 1 ;;
+val inc : int -> int = <fun>
+# let a = 99 ;;
+val a : int = 99
+```
+
+For a source file you can use "ocamlc -i /path/to/file.ml" command
+to print all names and signatures.
+
+```
+$ cat sigtest.ml
+let inc x = x + 1
+let add x y = x + y
+
+let a = 1
+
+$ ocamlc -i ./sigtest.ml
+val inc : int -> int
+val add : int -> int -> int
+val a : int
+```
+
+Note that type signatures of functions of multiple arguments are
+written in curried form.
+
+```ocaml
+(*** Comments ***)
+
+(* Comments are enclosed in (* and *). It's fine to nest comments. *)
+
+(* There are no single-line comments. *)
+
+
+(*** Variables and functions ***)
+
+(* Expressions can be separated by a double semicolon symbol, ";;".
+ In many cases it's redundant, but in this tutorial we use it after
+ every expression for easy pasting into the interpreter shell. *)
+
+(* Variable and function declarations use "let" keyword. *)
+let x = 10 ;;
+
+(* Since OCaml compiler infers types automatically, you normally don't need to
+ specify argument types explicitly. However, you can do it if you want or need to. *)
+let inc_int (x: int) = x + 1 ;;
+
+(* You need to mark recursive function definitions as such with "rec" keyword. *)
+let rec factorial n =
+ if n = 0 then 1
+ else factorial n * factorial (n-1)
+;;
+
+(* Function application usually doesn't need parentheses around arguments *)
+let fact_5 = factorial 5 ;;
+
+(* ...unless the argument is an expression. *)
+let fact_4 = factorial (5-1) ;;
+let sqr2 = sqr (-2) ;;
+
+(* Every function must have at least one argument.
+ Since some funcions naturally don't take any arguments, there's
+ "unit" type for it that has the only one value written as "()" *)
+let print_hello () = print_endline "hello world" ;;
+
+(* Note that you must specify "()" as argument when calling it. *)
+print_hello () ;;
+
+(* Calling a function with insufficient number of arguments
+ does not cause an error, it produces a new function. *)
+let make_inc x y = x + y ;; (* make_inc is int -> int -> int *)
+let inc_2 = make_inc 2 ;; (* inc_2 is int -> int *)
+inc_2 3 ;; (* Evaluates to 5 *)
+
+(* You can use multiple expressions in function body.
+ The last expression becomes the return value. All other
+ expressions must be of the "unit" type.
+ This is useful when writing in imperative style, the simplest
+ form of it is inserting a debug print. *)
+let print_and_return x =
+ print_endline (string_of_int x);
+ x
+;;
+
+(* Since OCaml is a functional language, it lacks "procedures".
+ Every function must return something. So functions that
+ do not really return anything and are called solely for their
+ side effects, like print_endline, return value of "unit" type. *)
+
+
+(* Definitions can be chained with "let ... in" construct.
+ This is roughly the same to assigning values to multiple
+ variables before using them in expressions in imperative
+ languages. *)
+let x = 10 in
+let y = 20 in
+x + y ;;
+
+(* Alternatively you can use "let ... and ... in" construct.
+ This is especially useful for mutually recursive functions,
+ with ordinary "let .. in" the compiler will complain about
+ unbound values.
+ It's hard to come up with a meaningful but self-contained
+ example of mutually recursive functions, but that syntax
+ works for non-recursive definitions too. *)
+let a = 3 and b = 4 in a * b ;;
+
+
+(*** Operators ***)
+
+(* There is little distintion between operators and functions.
+ Every operator can be called as a function. *)
+
+(+) 3 4 (* Same as 3 + 4 *)
+
+(* There's a number of built-in operators. One unusual feature is
+ that OCaml doesn't just refrain from any implicit conversions
+ between integers and floats, it also uses different operators
+ for floats. *)
+12 + 3 ;; (* Integer addition. *)
+12.0 +. 3.0 ;; (* Floating point addition. *)
+
+12 / 3 ;; (* Integer division. *)
+12.0 /. 3.0 ;; (* Floating point division. *)
+5 mod 2 ;; (* Remainder. *)
+
+(* Unary minus is a notable exception, it's polymorphic.
+ However, it also has "pure" integer and float forms. *)
+- 3 ;; (* Polymorphic, integer *)
+- 4.5 ;; (* Polymorphic, float *)
+~- 3 (* Integer only *)
+~- 3.4 (* Type error *)
+~-. 3.4 (* Float only *)
+
+(* You can define your own operators or redefine existing ones.
+ Unlike SML or Haskell, only selected symbols can be used
+ for operator names and first symbol defines associativity
+ and precedence rules. *)
+let (+) a b = a - b ;; (* Surprise maintenance programmers. *)
+
+(* More useful: a reciprocal operator for floats.
+ Unary operators must start with "~". *)
+let (~/) x = 1.0 /. x ;;
+~/4.0 (* = 0.25 *)
+
+
+(*** Built-in datastructures ***)
+
+(* Lists are enclosed in square brackets, items are separated by
+ semicolons. *)
+let my_list = [1; 2; 3] ;;
+
+(* Tuples are (optionally) enclosed in parentheses, items are separated
+ by commas. *)
+let first_tuple = 3, 4 ;; (* Has type "int * int". *)
+let second_tuple = (4, 5) ;;
+
+(* Corollary: if you try to separate list items by commas, you get a list
+ with a tuple inside, probably not what you want. *)
+let bad_list = [1, 2] ;; (* Becomes [(1, 2)] *)
+
+(* You can access individual list items with the List.nth function. *)
+List.nth my_list 1 ;;
+
+(* You can add an item to the beginning of a list with the "::" constructor
+ often referred to as "cons". *)
+1 :: [2; 3] ;; (* Gives [1; 2; 3] *)
+
+(* Arrays are enclosed in [| |] *)
+let my_array = [| 1; 2; 3 |] ;;
+
+(* You can access array items like this: *)
+my_array.(0) ;;
+
+
+
+(*** User-defined data types ***)
+
+(* You can define types with the "type some_type =" construct. Like in this
+ useless type alias: *)
+type my_int = int ;;
+
+(* More interesting types include so called type constructors.
+ Constructors must start with a capital letter. *)
+type ml = OCaml | StandardML ;;
+let lang = OCaml ;; (* Has type "ml". *)
+
+(* Type constructors don't need to be empty. *)
+type my_number = PlusInfinity | MinusInfinity | Real of float ;;
+let r0 = Real (-3.4) ;; (* Has type "my_number". *)
+
+(* Can be used to implement polymorphic arithmetics. *)
+type number = Int of int | Float of float ;;
+
+(* Point on a plane, essentially a type-constrained tuple *)
+type point2d = Point of float * float ;;
+let my_point = Point (2.0, 3.0) ;;
+
+(* Types can be parameterized, like in this type for "list of lists
+ of anything". 'a can be substituted with any type. *)
+type 'a list_of_lists = 'a list list ;;
+type int_list_list = int list_of_lists ;;
+
+(* Types can also be recursive. Like in this type analogous to
+ built-in list of integers. *)
+type my_int_list = EmptyList | IntList of int * my_int_list ;;
+let l = Cons (1, EmptyList) ;;
+
+
+(*** Pattern matching ***)
+
+(* Pattern matching is somewhat similar to switch statement in imperative
+ languages, but offers a lot more expressive power.
+
+ Even though it may look complicated, it really boils down to matching
+ an argument against an exact value, a predicate, or a type constructor. The type system
+ is what makes it so powerful. *)
+
+(** Matching exact values. **)
+
+let is_zero x =
+ match x with
+ | 0 -> true
+ | _ -> false (* The "_" pattern means "anything else". *)
+;;
+
+(* Alternatively, you can use the "function" keyword. *)
+let is_one x = function
+| 1 -> true
+| _ -> false
+;;
+
+(* Matching predicates, aka "guarded pattern matching". *)
+let abs x =
+ match x with
+ | x when x < 0 -> -x
+ | _ -> x
+;;
+
+abs 5 ;; (* 5 *)
+abs (-5) (* 5 again *)
+
+(** Matching type constructors **)
+
+type animal = Dog of string | Cat of string ;;
+
+let say x =
+ match x with
+ | Dog x -> x ^ " says woof"
+ | Cat x -> x ^ " says meow"
+;;
+
+say (Cat "Fluffy") ;; (* "Fluffy says meow". *)
+
+(** Traversing datastructures with pattern matching **)
+
+(* Recursive types can be traversed with pattern matching easily.
+ Let's see how we can traverse a datastructure of the built-in list type.
+ Even though the built-in cons ("::") looks like an infix operator, it's actually
+ a type constructor and can be matched like any other. *)
+let rec sum_list l =
+ match l with
+ | [] -> 0
+ | head :: tail -> head + (sum_list tail)
+;;
+
+sum_list [1; 2; 3] ;; (* Evaluates to 6 *)
+
+(* Built-in syntax for cons obscures the structure a bit, so we'll make
+ our own list for demonstration. *)
+
+type int_list = Nil | Cons of int * int_list ;;
+let rec sum_int_list l =
+ match l with
+ | Nil -> 0
+ | Cons (head, tail) -> head + (sum_int_list tail)
+;;
+
+let t = Cons (1, Cons (2, Cons (3, Nil))) ;;
+sum_int_list t ;;
+
+```
+
+## Further reading
+
+* Visit the official website to get the compiler and read the docs: <http://ocaml.org/>
+* Try interactive tutorials and a web-based interpreter by OCaml Pro: <http://try.ocamlpro.com/>
+* Read "OCaml for the skeptical" course: <http://www2.lib.uchicago.edu/keith/ocaml-class/home.html>
diff --git a/python.html.markdown b/python.html.markdown
index 9057dde2..390c7b76 100644
--- a/python.html.markdown
+++ b/python.html.markdown
@@ -57,9 +57,17 @@ to Python 2.x. Look for another tour of Python 3 soon!
# Enforce precedence with parentheses
(1 + 3) * 2 # => 8
-# Boolean values are primitives
-True
-False
+# Boolean Operators
++# Note "and" and "or" are case-sensitive
++True and False #=> False
++False or True #=> True
++
++# Note using Bool operators with ints
++0 and 2 #=> 0
++-5 or 0 #=> -5
++0 == False #=> True
++2 == True #=> False
+1 == True #=> True
# negate with not
not True # => False
diff --git a/python3.html.markdown b/python3.html.markdown
index f6babaff..a94f4eae 100644
--- a/python3.html.markdown
+++ b/python3.html.markdown
@@ -61,6 +61,18 @@ False
not True # => False
not False # => True
+# Boolean Operators
+# Note "and" and "or" are case-sensitive
+True and False #=> False
+False or True #=> True
+
+# Note using Bool operators with ints
+0 and 2 #=> 0
+-5 or 0 #=> -5
+0 == False #=> True
+2 == True #=> False
+1 == True #=> True
+
# Equality is ==
1 == 1 # => True
2 == 1 # => False
@@ -127,7 +139,8 @@ bool({}) #=> False
# Python has a print function
print("I'm Python. Nice to meet you!")
-# No need to declare variables before assigning to them. Convention is to use lower_case_with_underscores
+# No need to declare variables before assigning to them.
+# Convention is to use lower_case_with_underscores
some_var = 5
some_var # => 5
@@ -176,7 +189,8 @@ li[::-1] # => [3, 4, 2, 1]
del li[2] # li is now [1, 2, 3]
# You can add lists
-li + other_li # => [1, 2, 3, 4, 5, 6] - Note: values for li and for other_li are not modified.
+# Note: values for li and for other_li are not modified.
+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]
@@ -215,14 +229,17 @@ 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.
-list(filled_dict.keys()) # => ["three", "two", "one"]
+# 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.
+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.
-list(filled_dict.values()) # => [3, 2, 1]
# Note - Same as above regarding key ordering.
+list(filled_dict.values()) # => [3, 2, 1]
+
# Check for existence of keys in a dictionary with "in"
"one" in filled_dict # => True
@@ -242,6 +259,10 @@ filled_dict.get("four", 4) # => 4
filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5
filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5
+# Adding to a dictionary
+filled_dict.update({"four":4}) #=> {"one": 1, "two": 2, "three": 3, "four": 4}
+#filled_dict["four"] = 4 #another way to add to dict
+
# Remove keys from a dictionary with del
del filled_dict["one"] # Removes the key "one" from filled dict
@@ -458,6 +479,7 @@ map(add_10, [1, 2, 3]) # => [11, 12, 13]
filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
# We can use list comprehensions for nice maps and filters
+# List comprehension stores the output as a list which can itself be a nested list
[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]
diff --git a/ru-ru/python-ru.html.markdown b/ru-ru/python-ru.html.markdown
index 204eb357..d59d3e21 100644
--- a/ru-ru/python-ru.html.markdown
+++ b/ru-ru/python-ru.html.markdown
@@ -5,25 +5,29 @@ contributors:
- ["Louie Dinh", "http://ldinh.ca"]
translators:
- ["Yury Timofeev", "http://twitter.com/gagar1n"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
filename: learnpython-ru.py
---
-Язык Python был создан Гвидо ван Россумом в начале 90-х. Сейчас это один из самых популярных
-языков. Я люблю его за его понятный и доходчивый синтаксис - это почти что исполняемый псевдокод.
+Язык Python был создан Гвидо ван Россумом в начале 90-х. Сейчас это один из
+самых популярных языков. Я люблю его за понятный и доходчивый синтаксис — это
+почти что исполняемый псевдокод.
-С благодарностью жду ваших отзывов: [@louiedinh](http://twitter.com/louiedinh) или louiedinh [at] [google's email service]
+С благодарностью жду ваших отзывов: [@louiedinh](http://twitter.com/louiedinh)
+или louiedinh [at] [почтовый сервис Google]
-Замечание: Эта статья относится к Python 2.7, но должно работать и в Python 2.x. Скоро будет версия и для Python 3!
+Замечание: Эта статья относится к Python 2.7, но должно работать и в Python 2.x.
+Скоро будет версия и для Python 3!
```python
-# Однострочные комментарии начинаются с hash-символа.
+# Однострочные комментарии начинаются с символа решётки.
""" Многострочный текст может быть
записан, используя 3 знака " и обычно используется
в качестве комментария
"""
####################################################
-## 1. Примитивные типы данных и операторов
+## 1. Примитивные типы данных и операторы
####################################################
# У вас есть числа
@@ -36,17 +40,31 @@ filename: learnpython-ru.py
35 / 5 #=> 7
# А вот деление немного сложнее. В этом случае происходит деление
-# целых чисел и результат автоматически округляется в меньшую сторону.
+# целых чисел, и результат автоматически округляется в меньшую сторону.
5 / 2 #=> 2
-# Чтобы научиться делить, сначала нужно немного узнать о дробных числах.
-2.0 # Это дробное число
+# Чтобы научиться делить, сначала нужно немного узнать о числах
+# с плавающей запятой.
+2.0 # Это число с плавающей запятой
11.0 / 4.0 #=> 2.75 Вооот... Так гораздо лучше
+# Результат целочисленного деления округляется в меньшую сторону
+# как для положительных, так и для отрицательных чисел.
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # работает и для чисел с плавающей запятой
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
+
+# Остаток от деления
+7 % 3 # => 1
+
+# Возведение в степень
+2 ** 4 # => 16
+
# Приоритет операций указывается скобками
(1 + 3) * 2 #=> 8
-# Логические значения являются примитивами
+# Логические (булевы) значения являются примитивами
True
False
@@ -54,15 +72,15 @@ False
not True #=> False
not False #=> True
-# Равенство это ==
+# Равенство — это ==
1 == 1 #=> True
2 == 1 #=> False
-# Неравенство это !=
+# Неравенство — это !=
1 != 1 #=> False
2 != 1 #=> True
-# Еще немного сравнений
+# Ещё немного сравнений
1 < 10 #=> True
1 > 10 #=> False
2 <= 2 #=> True
@@ -85,9 +103,10 @@ not False #=> True
# Символ % используется для форматирования строк, например:
"%s могут быть %s" % ("строки", "интерполированы")
-# Новый метод форматирования строк - использование метода format.
+# Новый способ форматирования строк — использование метода format.
# Это предпочитаемый способ.
"{0} могут быть {1}".format("строки", "форматированы")
+
# Если вы не хотите считать, можете использовать ключевые слова.
"{name} хочет есть {food}".format(name="Боб", food="лазанью")
@@ -95,7 +114,7 @@ not False #=> True
None #=> None
# Не используйте оператор равенства '=='' для сравнения
-# объектов с None. Используйте для этого 'is'
+# объектов с None. Используйте для этого «is»
"etc" is None #=> False
None is None #=> True
@@ -113,17 +132,18 @@ None is None #=> True
## 2. Переменные и коллекции
####################################################
-# Печатать довольно просто
-print "Я Python. Приятно познакомиться!"
-
+# У Python есть функция Print, доступная в версиях 2.7 и 3,
+print("Я Python. Приятно познакомиться!")
+# ...и старый оператор print, доступный в версиях 2.x, но удалённый в версии 3.
+print "И я тоже Python!"
# Необязательно объявлять переменные перед их инициализацией.
-some_var = 5 # По соглашению используется нижний_регистр_с_подчеркиваниями
+some_var = 5 # По соглашению используется нижний_регистр_с_подчёркиваниями
some_var #=> 5
-# При попытке доступа к неинициализированной переменной,
+# При попытке доступа к неинициализированной переменной
# выбрасывается исключение.
-# См. раздел "Поток управления" для информации об исключениях.
+# См. раздел «Поток управления» для информации об исключениях.
some_other_var # Выбрасывает ошибку именования
# if может быть использован как выражение
@@ -149,24 +169,30 @@ li[0] #=> 1
# Обратимся к последнему элементу
li[-1] #=> 3
-# Попытка выйти за границы массива приведет к IndexError
-li[4] # Выдает IndexError
+# Попытка выйти за границы массива приведёт к ошибке индекса
+li[4] # Выдаёт IndexError
# Можно обращаться к диапазону, используя "кусочный синтаксис" (slice syntax)
-# (Для тех, кто любит математику, это называется замкнуто/открытый интервал.)
+# (Для тех, кто любит математику, это называется замкнуто-открытый интервал).
li[1:3] #=> [2, 4]
# Опускаем начало
li[2:] #=> [4, 3]
# Опускаем конец
li[:3] #=> [1, 2, 4]
+# Выбираем каждый второй элемент
+li[::2] # =>[1, 4]
+# Переворачиваем список
+li[::-1] # => [3, 4, 2, 1]
+# Используйте сочетания всего вышеназванного для выделения более сложных кусков
+# li[начало:конец:шаг]
# Удаляем произвольные элементы из списка оператором del
del li[2] # [1, 2, 3]
# Вы можете складывать списки
-li + other_li #=> [1, 2, 3, 4, 5, 6] - Замечание: li и other_li остаются нетронутыми
+li + other_li #=> [1, 2, 3, 4, 5, 6] — Замечание: li и other_li не изменяются
-# Конкатенировать списки можно методом extend
+# Объединять списки можно методом extend
li.extend(other_li) # Теперь li содержит [1, 2, 3, 4, 5, 6]
# Проверить элемент на вхождение в список можно оператором in
@@ -176,12 +202,12 @@ li.extend(other_li) # Теперь li содержит [1, 2, 3, 4, 5, 6]
len(li) #=> 6
-# Кортежи - это такие списки, только неизменяемые
+# Кортежи — это такие списки, только неизменяемые
tup = (1, 2, 3)
tup[0] #=> 1
-tup[0] = 3 # Выдает TypeError
+tup[0] = 3 # Выдаёт TypeError
-# Все то же самое можно делать и с кортежами
+# Всё то же самое можно делать и с кортежами
len(tup) #=> 3
tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
tup[:2] #=> (1, 2)
@@ -203,33 +229,33 @@ filled_dict = {"one": 1, "two": 2, "three": 3}
# Значения ищутся по ключу с помощью оператора []
filled_dict["one"] #=> 1
-# Можно получить все ключи в виде списка
+# Можно получить все ключи в виде списка с помощью метода keys
filled_dict.keys() #=> ["three", "two", "one"]
-# Замечание - сохранение порядка ключей в словаре не гарантируется
+# Замечание: сохранение порядка ключей в словаре не гарантируется
# Ваши результаты могут не совпадать с этими.
-# Можно получить и все значения в виде списка
+# Можно получить и все значения в виде списка, используйте метод values
filled_dict.values() #=> [3, 2, 1]
-# То же самое замечание насчет порядка ключей справедливо и здесь
+# То же самое замечание насчёт порядка ключей справедливо и здесь
# При помощи оператора in можно проверять ключи на вхождение в словарь
"one" in filled_dict #=> True
1 in filled_dict #=> False
-# Попытка получить значение по несуществующему ключу выбросит KeyError
+# Попытка получить значение по несуществующему ключу выбросит ошибку ключа
filled_dict["four"] # KeyError
# Чтобы избежать этого, используйте метод get
filled_dict.get("one") #=> 1
filled_dict.get("four") #=> None
-# Метод get также принимает аргумент default, значение которого будет
+# Метод get также принимает аргумент по умолчанию, значение которого будет
# возвращено при отсутствии указанного ключа
filled_dict.get("one", 4) #=> 1
filled_dict.get("four", 4) #=> 4
-# Метод setdefault - это безопасный способ добавить новую пару ключ-значение в словарь
+# Метод setdefault вставляет пару ключ-значение, только если такого ключа нет
filled_dict.setdefault("five", 5) #filled_dict["five"] возвращает 5
-filled_dict.setdefault("five", 6) #filled_dict["five"] по прежнему возвращает 5
+filled_dict.setdefault("five", 6) #filled_dict["five"] по-прежнему возвращает 5
# Множества содержат... ну, в общем, множества
@@ -237,8 +263,8 @@ empty_set = set()
# Инициализация множества набором значений
some_set = set([1,2,2,3,4]) # some_set теперь равно set([1, 2, 3, 4])
-# Начиная с Python 2.7, вы можете использовать {} чтобы обьявить множество
-filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+# Начиная с Python 2.7, вы можете использовать {}, чтобы объявить множество
+filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
# Добавление новых элементов в множество
filled_set.add(5) # filled_set равно {1, 2, 3, 4, 5}
@@ -262,33 +288,33 @@ filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
## 3. Поток управления
####################################################
-# Для начала заведем переменную
+# Для начала заведём переменную
some_var = 5
# Так выглядит выражение if. Отступы в python очень важны!
-# результат: "some_var меньше, чем 10"
+# результат: «some_var меньше, чем 10»
if some_var > 10:
- print "some_var намного больше, чем 10."
+ print("some_var намного больше, чем 10.")
elif some_var < 10: # Выражение elif необязательно.
- print "some_var меньше, чем 10."
+ print("some_var меньше, чем 10.")
else: # Это тоже необязательно.
- print "some_var равно 10."
+ print("some_var равно 10.")
"""
Циклы For проходят по спискам
Результат:
- собака это млекопитающее
- кошка это млекопитающее
- мышь это млекопитающее
+ собака — это млекопитающее
+ кошка — это млекопитающее
+ мышь — это млекопитающее
"""
for animal in ["собака", "кошка", "мышь"]:
# Можете использовать оператор % для интерполяции форматированных строк
- print "%s это млекопитающее" % animal
+ print("%s — это млекопитающее" % animal)
"""
-`range(number)` возвращает список чисел
+«range(число)» возвращает список чисел
от нуля до заданного числа
Результат:
0
@@ -297,7 +323,7 @@ for animal in ["собака", "кошка", "мышь"]:
3
"""
for i in range(4):
- print i
+ print(i)
"""
Циклы while продолжаются до тех пор, пока указанное условие не станет ложным.
@@ -309,19 +335,24 @@ for i in range(4):
"""
x = 0
while x < 4:
- print x
- x += 1 # То же самое, что x = x + 1
+ print(x)
+ x += 1 # Краткая запись для x = x + 1
-# Обрабывайте исключения блоками try/except
+# Обрабатывайте исключения блоками try/except
# Работает в Python 2.6 и выше:
try:
- # Для выбора ошибки используется raise
- raise IndexError("Это IndexError")
+ # Чтобы выбросить ошибку, используется raise
+ raise IndexError("Это ошибка индекса")
except IndexError as e:
# pass это просто отсутствие оператора. Обычно здесь происходит
- # восстановление от ошибки.
+ # восстановление после ошибки.
pass
+except (TypeError, NameError):
+ pass # Несколько исключений можно обработать вместе, если нужно.
+else: # Необязательное выражение. Должно следовать за последним блоком except
+ print("Всё хорошо!") # Выполнится, только если не было никаких исключений
+
####################################################
@@ -330,23 +361,23 @@ except IndexError as e:
# Используйте def для создания новых функций
def add(x, y):
- print "x равен %s, а y равен %s" % (x, y)
+ print("x равен %s, а y равен %s" % (x, y))
return x + y # Возвращайте результат выражением return
# Вызов функции с аргументами
-add(5, 6) #=> prints out "x равен 5, а y равен 6" и возвращает 11
+add(5, 6) #=> выводит «x равен 5, а y равен 6» и возвращает 11
-# Другой способ вызова функции с аргументами
+# Другой способ вызова функции — вызов с именованными аргументами
add(y=6, x=5) # Именованные аргументы можно указывать в любом порядке.
-# Вы можете определить функцию, принимающую неизвестное количество аргументов
+# Вы можете определить функцию, принимающую изменяемое число аргументов
def varargs(*args):
return args
varargs(1, 2, 3) #=> (1,2,3)
-# А также можете определить функцию, принимающую изменяющееся количество
+# А также можете определить функцию, принимающую изменяемое число
# именованных аргументов
def keyword_args(**kwargs):
return kwargs
@@ -356,8 +387,8 @@ keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
# Если хотите, можете использовать оба способа одновременно
def all_the_args(*args, **kwargs):
- print args
- print kwargs
+ print(args)
+ print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) выводит:
(1, 2)
@@ -368,11 +399,28 @@ all_the_args(1, 2, a=3, b=4) выводит:
# Используйте символ * для передачи кортежей и ** для передачи словарей
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
-all_the_args(*args) # эквивалент foo(1, 2, 3, 4)
-all_the_args(**kwargs) # эквивалент foo(a=3, b=4)
-all_the_args(*args, **kwargs) # эквивалент foo(1, 2, 3, 4, a=3, b=4)
+all_the_args(*args) # эквивалентно foo(1, 2, 3, 4)
+all_the_args(**kwargs) # эквивалентно foo(a=3, b=4)
+all_the_args(*args, **kwargs) # эквивалентно foo(1, 2, 3, 4, a=3, b=4)
-# Python имеет функции первого класса
+# Область определения функций
+x = 5
+
+def setX(num):
+ # Локальная переменная x — это не то же самое, что глобальная переменная x
+ x = num # => 43
+ print (x) # => 43
+
+def setGlobalX(num):
+ global x
+ print (x) # => 5
+ x = num # Глобальная переменная x теперь равна 6
+ print (x) # => 6
+
+setX(43)
+setGlobalX(6)
+
+# В Python есть функции первого класса
def create_adder(x):
def adder(y):
return x + y
@@ -388,7 +436,7 @@ add_10(3) #=> 13
map(add_10, [1,2,3]) #=> [11, 12, 13]
filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
-# Мы можем использовать списки для удобного отображения и фильтрации
+# Для удобного отображения и фильтрации можно использовать списочные включения
[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
@@ -402,7 +450,11 @@ class Human(object):
# Атрибут класса. Он разделяется всеми экземплярами этого класса
species = "H. sapiens"
- # Обычный конструктор
+ # Обычный конструктор, вызывается при инициализации экземпляра класса
+ # Обратите внимание, что двойное подчёркивание в начале и в конце имени
+ # означает объекты и атрибуты, которые используются Python, но находятся
+ # в пространствах имён, управляемых пользователем.
+ # Не придумывайте им имена самостоятельно.
def __init__(self, name):
# Присваивание значения аргумента атрибуту класса name
self.name = name
@@ -423,17 +475,17 @@ class Human(object):
return "*grunt*"
-# Инстанцирование класса
+# Инициализация экземпляра класса
i = Human(name="Иван")
-print i.say("привет") # "Иван: привет"
+print(i.say("привет")) # Выводит: «Иван: привет»
-j = Human("Петр")
-print j.say("Привет") # "Петр: привет"
+j = Human("Пётр")
+print(j.say("Привет")) # Выводит: «Пётр: привет»
# Вызов метода класса
i.get_species() #=> "H. sapiens"
-# Присвоение разделяемому атрибуту
+# Изменение разделяемого атрибута
Human.species = "H. neanderthalensis"
i.get_species() #=> "H. neanderthalensis"
j.get_species() #=> "H. neanderthalensis"
@@ -448,12 +500,12 @@ Human.grunt() #=> "*grunt*"
# Вы можете импортировать модули
import math
-print math.sqrt(16) #=> 4
+print(math.sqrt(16)) #=> 4
# Вы можете импортировать отдельные функции модуля
from math import ceil, floor
-print ceil(3.7) #=> 4.0
-print floor(3.7) #=> 3.0
+print(ceil(3.7)) #=> 4.0
+print(floor(3.7)) #=> 3.0
# Можете импортировать все функции модуля.
# (Хотя это и не рекомендуется)
@@ -463,7 +515,7 @@ from math import *
import math as m
math.sqrt(16) == m.sqrt(16) #=> True
-# Модули в Python это обычные файлы с кодом python. Вы
+# Модули в Python — это обычные Python-файлы. Вы
# можете писать свои модули и импортировать их. Название
# модуля совпадает с названием файла.
@@ -472,18 +524,72 @@ math.sqrt(16) == m.sqrt(16) #=> True
import math
dir(math)
+####################################################
+## 7. Дополнительно
+####################################################
+
+# Генераторы помогут выполнить ленивые вычисления
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+
+# Генератор создаёт значения на лету.
+# Он не возвращает все значения разом, а создаёт каждое из них при каждой
+# итерации. Это значит, что значения больше 15 в double_numbers
+# обработаны не будут.
+# Обратите внимание: xrange — это генератор, который делает то же, что и range.
+# Создание списка чисел от 1 до 900000000 требует много места и времени.
+# xrange создаёт объект генератора, а не список сразу, как это делает range.
+# Если нам нужно имя переменной, совпадающее с ключевым словом Python,
+# мы используем подчёркивание в конце
+xrange_ = xrange(1, 900000000)
+
+# Будет удваивать все числа, пока результат не будет >= 30
+for i in double_numbers(xrange_):
+ print(i)
+ if i >= 30:
+ break
+
+
+# Декораторы
+# В этом примере beg оборачивает say
+# Метод beg вызовет say. Если say_please равно True,
+# он изменит возвращаемое сообщение
+from functools import wraps
+
+
+def beg(target_function):
+ @wraps(target_function)
+ def wrapper(*args, **kwargs):
+ msg, say_please = target_function(*args, **kwargs)
+ if say_please:
+ return "{} {}".format(msg, " Пожалуйста! У меня нет денег :(")
+ return msg
+
+ return wrapper
+
+
+@beg
+def say(say_please=False):
+ msg = "Вы не купите мне пива?"
+ return msg, say_please
+
+
+print(say()) # Вы не купите мне пива?
+print(say(say_please=True)) # Вы не купите мне пива? Пожалуйста! У меня нет денег :(
```
-## Хотите еще?
+## Хотите ещё?
### Бесплатные онлайн-материалы
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
* [Dive Into Python](http://www.diveintopython.net/)
-* [The Official Docs](http://docs.python.org/2.6/)
+* [Официальная документация](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)
### Платные
diff --git a/tmux.html.markdown b/tmux.html.markdown
new file mode 100644
index 00000000..8d7aa752
--- /dev/null
+++ b/tmux.html.markdown
@@ -0,0 +1,244 @@
+---
+category: tool
+tool: tmux
+contributors:
+ - ["kaernyk", "http://github.com/kaernyk"]
+filename: LearnTmux.txt
+---
+
+
+<a href="http://tmux.sourceforge.net/">
+tmux</a> is a terminal multiplexer: it enables a number of terminals
+to be created, accessed, and controlled from a single screen. tmux
+may be detached from a screen and continue running in the background
+then later reattached.
+
+
+```
+ tmux [command] # Run a command
+ # 'tmux' with no commands will create a new
+ session
+
+ new # Create a new session
+ -s "Session" # Create named session
+ -n "Window" # Create named Window
+ -c "/dir" # Start in target directory
+
+ attach # Attach last/available session
+ -t "#" # Attach target session
+ -d # Detach the session from other instances
+
+ ls # List open sessions
+ -a # List all open sessions
+
+ lsw # List windows
+ -a # List all windows
+ -s # List all windows in session
+
+ lsp # List panes
+ -a # List all panes
+ -s # List all panes in session
+ -t # List app panes in target
+
+ kill-window # Kill current window
+ -t "#" # Kill target window
+ -a # Kill all windows
+ -a -t "#" # Kill all windows but the target
+
+ kill-session # Kill current session
+ -t "#" # Kill target session
+ -a # Kill all sessions
+ -a -t "#" # Kill all sessions but the target
+
+
+
+## Key Bindings
+
+# The method of controlling an attached tmux session is via key
+# combinations called 'Prefix' keys.
+
+----------------------------------------------------------------------
+ (C-b) = Ctrl + b # 'Prefix' combination required to use keybinds
+
+ (M-1) = Meta + 1 -or- Alt + 1
+----------------------------------------------------------------------
+
+ ? # List all key bindings
+ : # Enter the tmux command prompt
+ r # Force redraw of the attached client
+ c # Create a new window
+
+ ! # Break the current pane out of the window.
+ % # Split the current pane into two, left and right
+ " # Split the current pane into two, top and bottom
+
+ n # Change to the next window
+ p # Change to the previous window
+ { # Swap the current pane with the previous pane
+ } # Swap the current pane with the next pane
+
+ s # Select a new session for the attached client
+ interactively
+ w # Choose the current window interactively
+ 0 to 9 # Select windows 0 to 9
+
+ d # Detach the current client
+ D # Choose a client to detach
+
+ & # Kill the current window
+ x # Kill the current pane
+
+ Up, Down # Change to the pane above, below, left, or right
+ Left, Right
+
+ M-1 to M-5 # Arrange panes:
+ # 1) even-horizontal
+ # 2) even-vertical
+ # 3) main-horizontal
+ # 4) main-vertical
+ # 5) tiled
+
+ C-Up, C-Down # Resize the current pane in steps of one cell
+ C-Left, C-Right
+
+ M-Up, M-Down # Resize the current pane in steps of five cells
+ M-Left, M-Right
+
+
+
+### Configuring ~/.tmux.conf
+
+ tmux.conf can be used to set options automatically on start up, much
+like how .vimrc or init.el are used.
+
+# Example tmux.conf
+# 2014.9
+
+
+### Keybinds
+######################################################################
+
+# Unbind C-b as the default prefix
+unbind-key C-befix C-a
+
+# Return to previous window when prefix is pressed twice
+bind-key C-a last-window
+bind-key ` last-window
+
+# Allow swapping C-a and ` using F11/F12
+bind-key F11 set-option -g prefix C-a
+bind-key F12 set-option -g prefix `
+
+# Activate inner-most session (when nesting tmux)
+# to send commands
+bind-key a send-prefix
+
+# Index Start
+set -g base-index 1
+
+# Window Cycle/Swap
+bind e previous-window
+bind f next-window
+bind E swap-window -t -1
+bind F swap-window -t +1
+
+# easy-to-remember split pane commands
+bind | split-window -h
+bind - split-window -v
+unbind '"'
+unbind %
+
+# moving between panes with vim movement keys
+bind h select-pane -L
+bind j select-pane -D
+bind k select-pane -U
+bind l select-pane -R
+
+
+### Theme
+#####################################################################
+
+# Statusbar Color Palette
+set-option -g status-justify left
+set-option -g status-bg black
+set-option -g status-fg white
+set-option -g status-left-length 40
+set-option -g status-right-length 80
+
+# Pane Border Color Palette
+set-option -g pane-active-border-fg green
+set-option -g pane-active-border-bg black
+set-option -g pane-border-fg white
+set-option -g pane-border-bg black
+
+# Message Color Palette
+set-option -g message-fg black
+set-option -g message-bg green
+
+# Window Status Color Palette
+setw -g window-status-bg black
+setw -g window-status-current-fg green
+setw -g window-status-bell-attr default
+setw -g window-status-bell-fg red
+setw -g window-status-content-attr default
+setw -g window-status-content-fg yellow
+setw -g window-status-activity-attr default
+setw -g window-status-activity-fg yellow
+
+
+### UI
+######################################################################
+
+# Statusbar
+set-option -g status-utf8 on
+
+# Keybind preference
+setw -g mode-keys vi
+set-option -g status-keys vi
+
+# Notification
+setw -g monitor-activity on
+set -g visual-activity on
+set-option -g bell-action any
+set-option -g visual-bell off
+
+# Mouse
+setw -g mode-mouse on
+set-option -g mouse-select-pane on
+set -g mouse-resize-pane on
+set -g mouse-select-window on
+
+# Automatically set window titles
+set-option -g set-titles on
+
+# window number,program name,active (or not)
+set-option -g set-titles-string '#H:#S.#I.#P #W #T'
+
+# Statusbar Adjustments
+set -g status-left '#[fg=red]#H#[fg=green]:#[fg=white]#S #[fg=green]][#[default]'
+set -g status-interval 3
+
+# Statusbar with right-aligned Date / Time
+#set -g status-right '#[fg=green]][#[fg=white] #T #[fg=green]][ #[fg=blue]%Y-%m-%d #[fg=white]%H:%M#[default]'
+
+# Show performance counters in statusbar
+# Requires https://github.com/thewtex/tmux-mem-cpu-load/
+#set -g status-right '#[fg=green]][#[fg=white] #(tmux-mem-cpu-load 5 4) #[fg=green]][ #[fg=yellow]%H:%M#[default]'
+
+
+### Misc
+######################################################################
+
+# Scrollback/History limit
+set -g history-limit 4096
+
+bind r source-file ~/.tmux.conf
+```
+
+### External Resources
+
+<a href="http://tmux.sourceforge.net/">Tmux | Home</a><br>
+<a href="http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/tmux.1?query=tmux">Tmux Manual page</a><br>
+<a href="http://wiki.gentoo.org/wiki/Tmux">Archlinux Wiki</a><br>
+<a href="https://wiki.archlinux.org/index.php/Tmux">Gentoo Wiki</a><br>
+<a href="https://stackoverflow.com/questions/11558907/is-there-a-better-way-to-display-cpu-usage-in-tmux">Display CPU/MEM % in statusbar</a><br>
diff --git a/zh-cn/lua-cn.html.markdown b/zh-cn/lua-cn.html.markdown
index 95a94c76..3ba098ec 100644
--- a/zh-cn/lua-cn.html.markdown
+++ b/zh-cn/lua-cn.html.markdown
@@ -9,6 +9,7 @@ contributors:
- ["Amr Tamimi", "https://amrtamimi.com"]
translators:
- ["Jakukyo Friel", "http://weakish.github.io"]
+filename: lua-cn.lua
---
```lua
diff --git a/zh-cn/markdown-cn.html.markdown b/zh-cn/markdown-cn.html.markdown
index caecdc58..eecb8c5b 100644
--- a/zh-cn/markdown-cn.html.markdown
+++ b/zh-cn/markdown-cn.html.markdown
@@ -3,7 +3,7 @@ language: Markdown
contributors:
- ["Dan Turkel", "http://danturkel.com/"]
translators:
- - ["Fangzhou Chen"]
+ - ["Fangzhou Chen","https://github.com/FZSS"]
filename: learnmarkdown-cn.md
lang: zh-cn
---