mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2025-08-12 09:44:24 +02:00
Merge branch 'master' of github.com:adambard/learnxinyminutes-docs
This commit is contained in:
@@ -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
|
||||
|
349
c++.html.markdown
Normal file
349
c++.html.markdown
Normal file
@@ -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/
|
@@ -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
|
||||
|
@@ -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>
|
||||
|
@@ -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
|
||||
```
|
@@ -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! -->
|
||||
|
||||

|
||||

|
||||
|
||||
<!-- 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"
|
||||
|
||||
|
311
ocaml.html.markdown
Normal file
311
ocaml.html.markdown
Normal file
@@ -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>
|
@@ -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
|
||||
|
@@ -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]
|
||||
|
||||
|
@@ -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)
|
||||
|
||||
### Платные
|
||||
|
||||
|
244
tmux.html.markdown
Normal file
244
tmux.html.markdown
Normal file
@@ -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>
|
@@ -9,6 +9,7 @@ contributors:
|
||||
- ["Amr Tamimi", "https://amrtamimi.com"]
|
||||
translators:
|
||||
- ["Jakukyo Friel", "http://weakish.github.io"]
|
||||
filename: lua-cn.lua
|
||||
---
|
||||
|
||||
```lua
|
||||
|
@@ -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
|
||||
---
|
||||
|
Reference in New Issue
Block a user