diff options
38 files changed, 2174 insertions, 403 deletions
diff --git a/amd.html.markdown b/amd.html.markdown new file mode 100644 index 00000000..36210d03 --- /dev/null +++ b/amd.html.markdown @@ -0,0 +1,207 @@ +---
+category: tool
+tool: amd
+contributors:
+ - ["Frederik Ring", "https://github.com/m90"]
+filename: learnamd.js
+---
+
+## Getting Started with AMD
+
+The **Asynchronous Module Definition** API specifies a mechanism for defining
+JavaScript modules such that the module and its dependencies can be asynchronously
+loaded. This is particularly well suited for the browser environment where
+synchronous loading of modules incurs performance, usability, debugging, and
+cross-domain access problems.
+
+### Basic concept
+```javascript
+// The basic AMD API consists of nothing but two methods: `define` and `require`
+// and is all about module definition and consumption:
+// `define(id?, dependencies?, factory)` defines a module
+// `require(dependencies, callback)` imports a set of dependencies and
+// consumes them in the passed callback
+
+// Let's start by using define to define a new named module
+// that has no dependencies. We'll do so by passing a name
+// and a factory function to define:
+define('awesomeAMD', function(){
+ var isAMDAwesome = function(){
+ return true;
+ };
+ // The return value of a module's factory function is
+ // what other modules or require calls will receive when
+ // requiring our `awesomeAMD` module.
+ // The exported value can be anything, (constructor) functions,
+ // objects, primitives, even undefined (although that won't help too much).
+ return isAMDAwesome;
+});
+
+// Now, let's define another module that depends upon our `awesomeAMD` module.
+// Notice that there's an additional argument defining our
+// module's dependencies now:
+define('loudmouth', ['awesomeAMD'], function(awesomeAMD){
+ // dependencies will be passed to the factory's arguments
+ // in the order they are specified
+ var tellEveryone = function(){
+ if (awesomeAMD()){
+ alert('This is sOoOo rad!');
+ } else {
+ alert('Pretty dull, isn\'t it?');
+ }
+ };
+ return tellEveryone;
+});
+
+// As we do know how to use define now, let's use `require` to
+// kick off our program. `require`'s signature is `(arrayOfDependencies, callback)`.
+require(['loudmouth'], function(loudmouth){
+ loudmouth();
+});
+
+// To make this tutorial run code, let's implement a very basic
+// (non-asynchronous) version of AMD right here on the spot:
+function define(name, deps, factory){
+ // notice how modules without dependencies are handled
+ define[name] = require(factory ? deps : [], factory || deps);
+}
+
+function require(deps, callback){
+ var args = [];
+ // first let's retrieve all the dependencies needed
+ // by the require call
+ for (var i = 0; i < deps.length; i++){
+ args[i] = define[deps[i]];
+ }
+ // satisfy all the callback's dependencies
+ return callback.apply(null, args);
+}
+// you can see this code in action here: http://jsfiddle.net/qap949pd/
+```
+
+### Real-world usage with require.js
+
+In contrast to the introductory example, `require.js` (the most popular AMD library) actually implements the **A** in **AMD**, enabling you to load modules and their dependencies asynchronously via XHR:
+
+```javascript
+/* file: app/main.js */
+require(['modules/someClass'], function(SomeClass){
+ // the callback is deferred until the dependency is loaded
+ var thing = new SomeClass();
+});
+console.log('So here we are, waiting!'); // this will run first
+```
+
+By convention, you usually store one module in one file. `require.js` can resolve module names based on file paths, so you don't have to name your modules, but can simply reference them using their location. In the example `someClass` is assumed to be in the `modules` folder, relative to your configuration's `baseUrl`:
+
+* app/
+ * main.js
+ * modules/
+ * someClass.js
+ * someHelpers.js
+ * ...
+ * daos/
+ * things.js
+ * ...
+
+This means we can define `someClass` without specifying a module id:
+
+```javascript
+/* file: app/modules/someClass.js */
+define(['daos/things', 'modules/someHelpers'], function(thingsDao, helpers){
+ // module definition, of course, will also happen asynchronously
+ function SomeClass(){
+ this.method = function(){/**/};
+ // ...
+ }
+ return SomeClass;
+});
+```
+To alter the default path mapping behavior use `requirejs.config(configObj)` in your `main.js`:
+
+```javascript
+/* file: main.js */
+requirejs.config({
+ baseUrl : 'app',
+ paths : {
+ // you can also load modules from other locations
+ jquery : '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min',
+ coolLibFromBower : '../bower_components/cool-lib/coollib'
+ }
+});
+require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolLib, helpers){
+ // a `main` file needs to call require at least once,
+ // otherwise no code will ever run
+ coolLib.doFancyStuffWith(helpers.transform($('#foo')));
+});
+```
+`require.js`-based apps will usually have a single entry point (`main.js`) that is passed to the `require.js` script tag as a data-attribute. It will be automatically loaded and executed on pageload:
+```html
+<!DOCTYPE html>
+<html>
+<head>
+ <title>A hundred script tags? Never again!</title>
+</head>
+<body>
+ <script src="require.js" data-main="app/main"></script>
+</body>
+</html>
+```
+
+### Optimizing a whole project using r.js
+
+Many people prefer using AMD for sane code organization during development, but still want to ship a single script file in production instead of performing hundreds of XHRs on page load.
+
+`require.js` comes with a script called `r.js` (that you will probably run in node.js, although Rhino is supported too) that can analyse your project's dependency graph, and build a single file containing all your modules (properly named), minified and ready for consumption.
+
+Install it using `npm`:
+```sh
+$ npm install requirejs -g
+```
+Now you can feed it with a configuration file:
+```sh
+$ r.js -o app.build.js
+```
+For our above example the configuration might look like:
+```javascript
+/* file : app.build.js */
+({
+ name : 'main', // name of the entry point
+ out : 'main-built.js', // name of the file to write the output to
+ baseUrl : 'app',
+ paths : {
+ // `empty:` tells r.js that this should still be loaded from the CDN, using
+ // the location specified in `main.js`
+ jquery : 'empty:',
+ coolLibFromBower : '../bower_components/cool-lib/coollib'
+ }
+})
+```
+To use the built file in production, simply swap `data-main`:
+```html
+<script src="require.js" data-main="app/main-built"></script>
+```
+An incredibly detailed [overview of build options](https://github.com/jrburke/r.js/blob/master/build/example.build.js) is available in the GitHub repo.
+
+### Topics not covered in this tutorial
+* [Loader plugins / transforms](http://requirejs.org/docs/plugins.html)
+* [CommonJS style loading and exporting](http://requirejs.org/docs/commonjs.html)
+* [Advanced configuration](http://requirejs.org/docs/api.html#config)
+* [Shim configuration (loading non-AMD modules)](http://requirejs.org/docs/api.html#config-shim)
+* [CSS loading and optimizing with require.js](http://requirejs.org/docs/optimization.html#onecss)
+* [Using almond.js for builds](https://github.com/jrburke/almond)
+
+### Further reading:
+
+* [Official Spec](https://github.com/amdjs/amdjs-api/wiki/AMD)
+* [Why AMD?](http://requirejs.org/docs/whyamd.html)
+* [Universal Module Definition](https://github.com/umdjs/umd)
+
+### Implementations:
+
+* [require.js](http://requirejs.org)
+* [dojo toolkit](http://dojotoolkit.org/documentation/tutorials/1.9/modules/)
+* [cujo.js](http://cujojs.com/)
+* [curl.js](https://github.com/cujojs/curl)
+* [lsjs](https://github.com/zazl/lsjs)
+* [mmd](https://github.com/alexlawrence/mmd)
diff --git a/bash.html.markdown b/bash.html.markdown index dc7d32b6..11c1f3a2 100644 --- a/bash.html.markdown +++ b/bash.html.markdown @@ -9,6 +9,7 @@ contributors: - ["akirahirose", "https://twitter.com/akirahirose"] - ["Anton Strömkvist", "http://lutic.org/"] - ["Rahil Momin", "https://github.com/iamrahil"] + - ["Gregrory Kielian", "https://github.com/gskielian"] filename: LearnBash.sh --- @@ -199,4 +200,12 @@ sort file.txt uniq -d file.txt # prints only the first column before the ',' character cut -d ',' -f 1 file.txt +# replaces every occurrence of 'okay' with 'great' in file.txt, (regex compatible) +sed -i 's/okay/great/g' file.txt +# print to stdout all lines of file.txt which match some regex, the example prints lines which begin with "foo" and end in "bar" +grep "^foo.*bar$" file.txt +# pass the option "-c" to instead print the number of lines matching the regex +grep -c "^foo.*bar$" file.txt +# if you literally want to search for the string, and not the regex, use fgrep (or grep -F) +fgrep "^foo.*bar$" file.txt ``` diff --git a/c++.html.markdown b/c++.html.markdown index 5bf7e2ea..50de5eff 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -3,346 +3,588 @@ language: c++ filename: learncpp.cpp contributors: - ["Steven Basart", "http://github.com/xksteven"] + - ["Matt Kline", "https://github.com/mrkline"] 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++ is a systems programming language that, +[according to its inventor Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote), +was designed to + +- be a "better C" +- support data abstraction +- support object-oriented programming +- support generic programming + +Though its syntax can be more difficult or complex than newer languages, +it is widely used because it compiles to native instructions that can be +directly run by the processor and offers tight control over hardware (like C) +while offering high-level features such as generics, exceptions, and classes. +This combination of speed and functionality makes C++ +one of the most widely-used programming languages. ```c++ -/////////////////////////////////////// -// C++ differences -/////////////////////////////////////// +////////////////// +// Comparison to C +////////////////// + +// C++ is _almost_ a superset of C and shares its basic syntax for +// variable declarations, primitive types, and functions. +// However, C++ varies in some of the following ways: + +// A main() function in C++ should return an int, +// though void main() is accepted by most compilers (gcc, clang, etc.) +// This value serves as the program's exit status. +// See http://en.wikipedia.org/wiki/Exit_status for more information. +int main(int argc, char** argv) +{ + // Command line arguments are passed in by argc and argv in the same way + // they are in C. + // argc indicates the number of arguments, + // and argv is an array of C-style strings (char*) + // representing the arguments. + // The first argument is the name by which the program was called. + // argc and argv can be omitted if you do not care about arguments, + // giving the function signature of int main() + + // An exit status of 0 indicates success. + return 0; +} +// In C++, character literals are one byte. +sizeof('c') == 1 -//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, character literals are the same size as ints. +sizeof('c') == sizeof(10) -//In C -sizeof('c') == sizeof(10) //true chars are passed as ints +// C++ has strict prototyping +void func(); // function which accepts no arguments -//In C++ strict prototyping -void func(); //function which accepts no arguments +// In C +void func(); // function which may accept any number of 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 +// Use nullptr instead of NULL in C++ +int* ip = nullptr; +// C standard headers are available in C++, +// but are prefixed with "c" and have no .h suffix. +#include <cstdio> -//C++ Supports Function overloading -//Provided each function takes different -//parameters +int main() +{ + printf("Hello, world!\n"); + return 0; +} -void printing(char const *myString) -{printf("String %s\n",myString);} //Hello +/////////////////////// +// Function overloading +/////////////////////// -void printing(int myInt) -{printf("My int is %d",myInt);} //15 +// C++ supports function overloading +// provided each function takes different parameters. -int main () -{ - printing("Hello"); - printing(15); -} - +void print(char const* myString) +{ + printf("String %s\n", myString); +} +void print(int myInt) +{ + printf("My int is %d", myInt); +} -//C++ Default Function Arguments -void two_ints(int a = 1, int b = 4); +int main() +{ + print("Hello"); // Resolves to void print(const char*) + print(15); // Resolves to void print(int) +} -int main() -{ - two_ints(); // arguments: 1, 4 - two_ints(20); // arguments: 20, 4 - two_ints(20, 5); // arguments: 20, 5 -} +///////////////////////////// +// Default function arguments +///////////////////////////// +// You can provide default arguments for a function +// if they are not provided by the caller. -//C++ added the nullptr which is different from 0 -int *ip = nullptr; // OK -int value = nullptr; // error: value is no pointer +void doSomethingWithInts(int a = 1, int b = 4) +{ + // Do something with the ints here +} +int main() +{ + doSomethingWithInts(); // a = 1, b = 4 + doSomethingWithInts(20); // a = 20, b = 4 + doSomethingWithInts(20, 5); // a = 20, b = 5 +} -/////////////////////////////////////// -// C++ Additions ontop of C -/////////////////////////////////////// +// Default arguments must be at the end of the arguments list. +void invalidDeclaration(int a = 1, int b) // Error! +{ +} -/////////////////////////////////////// -// C++ Namespace -/////////////////////////////////////// -//Namespaces allow you to define your own -//functions and variables for use +///////////// +// Namespaces +///////////// + +// Namespaces provide separate scopes for variable, function, +// and other declarations. +// Namespaces can be nested. + +namespace First { + namespace Nested { + void foo() + { + printf("This is First::Nested::foo\n"); + } + } // end namespace Nested +} // end namespace First + +namespace Second { + void foo() + { + printf("This is Second::foo\n") + } +} -// Use '::' to change variable (or function) scope -// Putting '::' before a function or variable will -// reference a global scope +void foo() +{ + printf("This is global foo\n"); +} -// This allows you to make normal c library calls -// std is for standard library -using namespace std; +int main() +{ + // Assume everything is from the namespace "Second" + // unless otherwise specified. + using namespace Second; -#include <stdio.h> + foo(); // prints "This is Second::foo" + First::Nested::foo(); // prints "This is First::Nested::foo" + ::foo(); // prints "This is global foo" +} -int counter = 50; // global variable +/////////////// +// Input/Output +/////////////// -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 - } -} +// C++ input and output uses streams +// cin, cout, and cerr represent stdin, stdout, and stderr. +// << is the insertion operator and >> is the extraction operator. -// Namespaces can be nested +#include <iostream> // Include for I/O streams +using namespace std; // Streams are in the std namespace (standard library) -namespace myFirstNameSpace -{ - namespace myInnerSoul - { - cos(int x) - { - printf("My inner soul was made to program."); - } - } -} +int main() +{ + int myInt; -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); -} + // Prints to stdout (or terminal/screen) + cout << "Enter your favorite number:\n"; + // Takes in input + cin >> myInt; + // cout can also be formatted + cout << "Your favorite number is " << myInt << "\n"; + // prints "Your favorite number is <myInt>" -/////////////////////////////////////// -// C++ Strings -/////////////////////////////////////// + cerr << "Used for error messages"; +} -//Strings in C++ are Objects and have many functions -myString = "Hello"; -myOtherString = " World"; +////////// +// Strings +////////// -myString + myOtherString; // => "Hello World" +// Strings in C++ are objects and have many member functions +#include <string> -myString + ' You'; // => "Hello You" +using namespace std; // Strings are also in the namespace std (standard library) -myString != myOtherString; //True +string myString = "Hello"; +string myOtherString = " World"; -//An example of a string method -myString.append(" Dog"); // => "Hello Dog" +// + is used for concatenation. +cout << myString + myOtherString; // "Hello World" +cout << myString + " You"; // "Hello You" -/////////////////////////////////////// -// C++ Input Output -/////////////////////////////////////// +// C++ strings are mutable and have value semantics. +myString.append(" Dog"); +cout << myString; // "Hello Dog" -//C++ input and output streams -//cin, cout, cerr, << is insertion and >> is extraction operator -#include <iostream> -using namespace std; +///////////// +// References +///////////// -int main() -{ +// In addition to pointers like the ones in C, +// C++ has _references_. +// These are pointer types that cannot be reassigned once set +// and cannot be null. +// They also have the same syntax as the variable itself: +// No * is needed for dereferencing and +// & (address of) is not used for assignment. - int myInt; - - //Prints to stdout (or terminal/screen) - cout << "Enter your fav number:\n"; - //Takes in input - cin >> myInt; +using namespace std; - //cout can also be formatted - cout << "Your fav number is " << myInt << "\n"; - //Your fav number is ## +string foo = "I am foo"; +string bar = "I am bar"; - cerr << "Used for error messages"; -} +string& fooRef = foo; // This creates a reference to foo. +fooRef += ". Hi!"; // Modifies foo through the reference +cout << fooRef; // Prints "I am foo. Hi!" -/////////////////////////////////////// -// C++ Classes -/////////////////////////////////////// +fooRef = bar; // Error: references cannot be reassigned. +const string& barRef = bar; // Create a const reference to bar. +// Like C, const values (and pointers and references) cannot be modified. +barRef += ". Hi!"; // Error, const references cannot be modified. -//First example of classes -#include <iostream> +////////////////////////////////////////// +// Classes and object-oriented programming +////////////////////////////////////////// -//define a class -class Doggie -{ - std::string name; - int weight; +// First example of classes +#include <iostream> - // These are only the declarations - //Can also have private and protected - public: - //The public methods (can also include variables) +// Declare a class. +// Classes are usually declared in header (.h or .hpp) files. +class Dog { + // Member variables and functions are private by default. + std::string name; + int weight; - // Default constructor - Doggie(); +// All members following this are public +// until "private:" or "protected:" is found. +public: - void setName(std::string dogsName); - void setWeight(int dogsWeight); - void printDog(); + // Default constructor + Dog(); - //Can define functions within class declaration too - void dogBark() {std::cout << "Bark Bark\n"} + // Member function declarations (implementations to follow) + // Note that we use std::string here instead of placing + // using namespace std; + // above. + // Never put a "using namespace" statement in a header. + void setName(const std::string& dogsName); - //Destructors are methods that free the allocated space - ~doggieDestructor(); - //if no destructor compiler defines the trivial destructor + void setWeight(int dogsWeight); -//Classes are similar to structs and must close the } with ; -}; + // Functions that do not modify the state of the object + // should be marked as const. + // This allows you to call them if given a const reference to the object. + // Also note the functions must be explicitly declared as _virtual_ + // in order to be overridden in derived classes. + // Functions are not virtual by default for performance reasons. + virtual void print() const; -// 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; -} + // Functions can also be defined inside the class body. + // Functions defined as such are automatically inlined. + void bark() const { std::cout << name << " barks!\n" } -void Doggie::setWeight (int doggie_weight) { - weight = doggie_weight; -} + // Along with constructors, C++ provides destructors. + // These are called when an object is deleted or falls out of scope. + // This enables powerful paradigms such as RAII + // (see below) + // Destructors must be virtual to allow classes to be derived from this one. + virtual ~Dog(); -void Doggie::printDog () { - std::cout << "Dog is " << name << " weighs" << weight << "\n"; -} +}; // A semicolon must follow the class definition. -void Doggie::~doggieDestructor () { - delete[] name; - delete weight; -} +// Class member functions are usually implemented in .cpp files. +void Dog::Dog() +{ + std::cout << "A dog has been constructed\n"; +} -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; -} +// Objects (such as strings) should be passed by reference +// if you are modifying them or const reference if you are not. +void Dog::setName(const std::string& dogsName) +{ + name = doggie_name; +} +void Dog::setWeight(int dogsWeight) +{ + weight = dogsWeight; +} -//C++ Class inheritance +// Notice that "virtual" is only needed in the declaration, not the definition. +void Dog::print() const +{ + std::cout << "Dog is " << name << " and weighs " << weight << "kg\n"; +} -class German_Sheperd : public Doggie +void Dog::~Dog() { - //This class now inherits everything public and protected from Doggie class - - //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; + cout << "Goodbye " << name << "\n"; } +int main() { + Dog myDog; // prints "A dog has been constructed" + myDog.setName("Barkley"); + myDog.setWeight(10); + myDog.printDog(); // prints "Dog is Barkley and weighs 10 kg" + return 0; +} // prints "Goodbye Barkley" + +// Inheritance: + +// This class inherits everything public and protected from the Dog class +class OwnedDog : public Dog { + + void setOwner(const std::string& dogsOwner) + + // Override the behavior of the print function for all OwnedDogs. See + // http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping + // for a more general introduction if you are unfamiliar with + // subtype polymorphism. + // The override keyword is optional but makes sure you are actually + // overriding the method in a base class. + void print() const override; + +private: + std::string owner; +}; + +// Meanwhile, in the corresponding .cpp file: + +void OwnedDog::setOwner(const std::string& dogsOwner) +{ + owner = dogsOwner; +} + +void OwnedDog::print() const +{ + Dog::print(); // Call the print function in the base Dog class + std::cout << "Dog is owned by " << owner << "\n"; + // Prints "Dog is <name> and weights <weight>" + // "Dog is owned by <owner>" +} + +////////////////////////////////////////// +// Initialization and Operator Overloading +////////////////////////////////////////// + +// In C++ you can overload the behavior of operators such as +, -, *, /, etc. +// This is done by defining a function which is called +// whenever the operator is used. + +#include <iostream> +using namespace std; + +class Point { +public: + // Member variables can be given default values in this manner. + double x = 0; + double y = 0; + + // Define a default constructor which does nothing + // but initialize the Point to the default value (0, 0) + Point() { }; + + // The following syntax is known as an initialization list + // and is the proper way to initialize class member values + Point (double a, double b) : + x(a), + y(b) + { /* Do nothing except initialize the values */ } + + // Overload the + operator. + Point operator+(const Point& rhs) const; + + // Overload the += operator + Point& operator+=(const Point& rhs); + + // It would also make sense to add the - and -= operators, + // but we will skip those for brevity. +}; + +Point Point::operator+(const Point& rhs) const +{ + // Create a new point that is the sum of this one and rhs. + return Point(x + rhs.x, y + rhs.y); +} + +Point& Point::operator+=(const Point& rhs) +{ + x += rhs.x; + y += rhs.y; + return *this; +} + +int main () { + Point up (0,1); + Point right (1,0); + // This calls the Point + operator + // Point up calls the + (function) with right as its paramater + Point result = up + right; + // Prints "Result is upright (1,1)" + cout << "Result is upright (" << result.x << ',' << result.y << ")\n"; + return 0; +} + +///////////////////// +// Exception Handling +///////////////////// + +// The standard library provides a few exception types +// (see http://en.cppreference.com/w/cpp/error/exception) +// but any type can be thrown an as exception +#include <exception> + +// All exceptions thrown inside the _try_ block can be caught by subsequent +// _catch_ handlers. +try { + // Do not allocate exceptions on the heap using _new_. + throw std::exception("A problem occurred"); +} +// Catch exceptions by const reference if they are objects +catch (const std::exception& ex) +{ + std::cout << ex.what(); +// Catches any exception not caught by previous _catch_ blocks +} catch (...) +{ + std::cout << "Unknown exception caught"; + throw; // Re-throws the exception +} + +/////// +// RAII +/////// + +// RAII stands for Resource Allocation Is Initialization. +// It is often considered the most powerful paradigm in C++, +// and is the simple concept that a constructor for an object +// acquires that object's resources and the destructor releases them. + +// To understand how this is useful, +// consider a function that uses a C file handle: +void doSomethingWithAFile(const char* filename) +{ + // To begin with, assume nothing can fail. + + FILE* fh = fopen(filename, "r"); // Open the file in read mode. + + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + + fclose(fh); // Close the file handle. +} + +// Unfortunately, things are quickly complicated by error handling. +// Suppose fopen can fail, and that doSomethingWithTheFile and +// doSomethingElseWithIt return error codes if they fail. +// (Exceptions are the preferred way of handling failure, +// but some programmers, especially those with a C background, +// disagree on the utility of exceptions). +// We now have to check each call for failure and close the file handle +// if a problem occurred. +bool doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); // Open the file in read mode + if (fh == nullptr) // The returned pointer is null on failure. + reuturn false; // Report that failure to the caller. + + // Assume each function returns false if it failed + if (!doSomethingWithTheFile(fh)) { + fclose(fh); // Close the file handle so it doesn't leak. + return false; // Propagate the error. + } + if (!doSomethingElseWithIt(fh)) { + fclose(fh); // Close the file handle so it doesn't leak. + return false; // Propagate the error. + } + + fclose(fh); // Close the file handle so it doesn't leak. + return true; // Indicate success +} + +// C programmers often clean this up a little bit using goto: +bool doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); + if (fh == nullptr) + reuturn false; + + if (!doSomethingWithTheFile(fh)) + goto failure; + + if (!doSomethingElseWithIt(fh)) + goto failure; + + fclose(fh); // Close the file + return true; // Indicate success + +failure: + fclose(fh); + return false; // Propagate the error +} + +// If the functions indicate errors using exceptions, +// things are a little cleaner, but still sub-optimal. +void doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); // Open the file in read mode + if (fh == nullptr) + throw std::exception("Could not open the file."); + + try { + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + } + catch (...) { + fclose(fh); // Be sure to close the file if an error occurs. + throw; // Then re-throw the exception. + } + + fclose(fh); // Close the file + // Everything succeeded +} + +// Compare this to the use of C++'s file stream class (fstream) +// fstream uses its destructor to close the file. +// Recall from above that destructors are automatically called +// whenver an object falls out of scope. +void doSomethingWithAFile(const std::string& filename) +{ + // ifstream is short for input file stream + std::ifstream fh(filename); // Open the file + + // Do things with the file + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + +} // The file is automatically closed here by the destructor + +// This has _massive_ advantages: +// 1. No matter what happens, +// the resource (in this case the file handle) will be cleaned up. +// Once you write the destructor correctly, +// It is _impossible_ to forget to close the handle and leak the resource. +// 2. Note that the code is much cleaner. +// The destructor handles closing the file behind the scenes +// without you having to worry about it. +// 3. The code is exception safe. +// An exception can be thrown anywhere in the function and cleanup +// will still occur. + +// All idiomatic C++ code uses RAII extensively for all resources. +// Additional examples include +// - Memory using unique_ptr and shared_ptr +// - Containers - the standard library linked list, +// vector (i.e. self-resizing array), hash maps, and so on +// all automatically destroy their contents when they fall out of scope. +// - Mutexes using lock_guard and unique_lock ``` -Futher Reading +Futher Reading: + +An up-to-date language reference can be found at +<http://cppreference.com/w/cpp> -for more resources see: http://www.icce.rug.nl/documents/cplusplus/ -for other reference material: http://www.cplusplus.com/doc/tutorial/ +Additional resources may be found at <http://cplusplus.com> diff --git a/c.html.markdown b/c.html.markdown index 10e6fa45..6daabe94 100644 --- a/c.html.markdown +++ b/c.html.markdown @@ -5,6 +5,7 @@ contributors: - ["Adam Bard", "http://adambard.com/"] - ["Árpád Goretity", "http://twitter.com/H2CO3_iOS"] - ["Jakub Trzebiatowski", "http://cbs.stgn.pl"] + - ["Marco Scannadinari", "https://marcoms.github.io"] --- @@ -21,6 +22,10 @@ memory management and C will take you as far as you need to go. Multi-line comments look like this. They work in C89 as well. */ +/* +Multi-line comments don't nest /* Be careful */ // comment ends on this line... +*/ // ...not this one! + // Constants: #define <keyword> #define DAYS_IN_YEAR 365 @@ -74,10 +79,10 @@ int main() { long long x_long_long = 0; // floats are usually 32-bit floating point numbers - float x_float = 0.0; + float x_float = 0.0f; // 'f' suffix here denotes floating point literal // doubles are usually 64-bit floating-point numbers - double x_double = 0.0; + double x_double = 0.0; // real numbers without any suffix are doubles // Integral types may be unsigned. unsigned short ux_short; diff --git a/csharp.html.markdown b/csharp.html.markdown index 136f6c50..f6708590 100644 --- a/csharp.html.markdown +++ b/csharp.html.markdown @@ -508,7 +508,7 @@ on a new line! ""Wow!"", the masses cried"; // LINQ - maps a store to IQueryable<T> objects, with delayed execution // e.g. LinqToSql - maps to a database, LinqToXml maps to an xml document - var db = new BikeRespository(); + var db = new BikeRepository(); // execution is delayed, which is great when querying a database var filter = db.Bikes.Where(b => b.HasTassles); // no query run @@ -767,9 +767,9 @@ on a new line! ""Wow!"", the masses cried"; /// EntityFramework Code First is awesome (similar to Ruby's ActiveRecord, but bidirectional) /// http://msdn.microsoft.com/en-us/data/jj193542.aspx /// </summary> - public class BikeRespository : DbSet + public class BikeRepository : DbSet { - public BikeRespository() + public BikeRepository() : base() { } diff --git a/de-de/haskell-de.html.markdown b/de-de/haskell-de.html.markdown index df6267f9..2c548961 100644 --- a/de-de/haskell-de.html.markdown +++ b/de-de/haskell-de.html.markdown @@ -1,5 +1,5 @@ --- -language: haskell +language: Haskell lang: de-de contributors: - ["Adit Bhargava", "http://adit.io"] diff --git a/es-es/julia-es.html.markdown b/es-es/julia-es.html.markdown index 41a7c68b..203ee3bb 100644 --- a/es-es/julia-es.html.markdown +++ b/es-es/julia-es.html.markdown @@ -1,8 +1,9 @@ --- -language: julia +language: Julia contributors: - ["Leah Hanson", "http://leahhanson.us"] - - ["Guillermo Garza" ] +translators: + - ["Guillermo Garza", "http://github.com/ggarza"] filename: learnjulia-es.jl lang: es-es --- diff --git a/fr-fr/haskell.html.markdown b/fr-fr/haskell.html.markdown index 989db1d5..d9d3151f 100644 --- a/fr-fr/haskell.html.markdown +++ b/fr-fr/haskell.html.markdown @@ -1,5 +1,5 @@ --- -language: haskell +language: Haskell contributors: - ["Adit Bhargava", "http://adit.io"] translators: diff --git a/fr-fr/lua-fr.html.markdown b/fr-fr/lua-fr.html.markdown index 922d6ebc..b4e2a161 100644 --- a/fr-fr/lua-fr.html.markdown +++ b/fr-fr/lua-fr.html.markdown @@ -1,5 +1,5 @@ --- -language: lua +language: Lua filename: learnlua-fr.lua contributors: - ["Tyler Neylon", "http://tylerneylon.com/"] diff --git a/fr-fr/scala.html.markdown b/fr-fr/scala.html.markdown index da562138..a43edf16 100644 --- a/fr-fr/scala.html.markdown +++ b/fr-fr/scala.html.markdown @@ -1,12 +1,11 @@ --- language: Scala -filename: learnscala.scala contributors: - ["George Petrov", "http://github.com/petrovg"] - ["Dominic Bou-Samra", "http://dbousamra.github.com"] translators: - - ["Anne-Catherine Dehier", "https://github.com/spellart"] -filename: learn.scala + - ["Anne-Catherine Dehier", "https://github.com/spellart"] +filename: learnscala-fr.scala lang: fr-fr --- diff --git a/fr-fr/xml-fr.html.markdown b/fr-fr/xml-fr.html.markdown new file mode 100644 index 00000000..d7e76892 --- /dev/null +++ b/fr-fr/xml-fr.html.markdown @@ -0,0 +1,127 @@ +--- +language: xml +contributors: + - ["João Farias", "https://github.com/JoaoGFarias"] +translators: + - ["Geoffrey Liu", "https://github.com/g-liu"] +filename: learnxml.xml +--- + +XML est un langage de balisage conçu pour stocker et transporter les informations. + +Contrairement à HTML, XML ne spécifie pas comment afficher ou formater les informations, juste comment les porter. + +* La syntaxe XML + +```xml +<!-- Les commentaires en XML ressemblent ceci --> + +<?xml version="1.0" encoding="UTF-8"?> +<librairie> + <livre categorie="CUISINE"> + <titre lang="en">Everyday Italian</titre> + <auteur>Giada De Laurentiis</auteur> + <an>2005</an> + <prix>30.00</prix> + </livre> + <livre categorie="ENFANTS"> + <titre lang="en">Harry Potter</titre> + <auteur>J. K. Rowling</auteur> + <an>2005</an> + <prix>29.99</prix> + </livre> + <livre categorie="WEB"> + <titre lang="en">Learning XML</titre> + <auteur>Erik T. Ray</auteur> + <an>2003</an> + <prix>39.95</prix> + </livre> +</librairie> + +<!-- Ce qui suit est un fichier XML typique. + Il commence par une déclaration, qui informe certaines métadonnées (en option). + +XML utilise une structure arborescente. Ci-dessus, le nœud racine est «librairie», qui a + trois nœuds enfants, qui sont appelés «livres». Ces nœuds ont plus de nœuds enfants, et ainsi de suite ... + +On crée les nœuds avec des balises d'ouverture / fermeture, et les enfants sont les nœuds juste entre + les balises d'ouverture et de fermeture. --> + + +<!-- XML porte deux types d'informations: + 1 - Les attributs -> les métadonnées sur un nœud. + Habituellement, l'analyseur XML utilise cette information pour bien stocker les données. + 2 - Les éléments -> les informations pures. + C'est ce que l'analyseur retrouvera du fichier XML. + Les éléments apparaissent entre les balises d'ouverture et de fermeture, sans parenthèses. --> + + +<!-- Ci-dessous, un élément avec deux attributs --> +<fichier type="gif" id="4293">ordinateur.gif</fichier> + + +``` + +* Un document bien formaté & le validation + +Un document XML est bien formaté s'il est syntaxiquement correct. +Cependant, il est possible d'injecter plus de contraintes dans le document, +en utilisant les définitions de documents, tels que les schémas DTD et XML. + +Un document XML qui suit une définition de document est dit valide, +en ce qui concerne ce document. + +Avec cet outil, vous pouvez vérifier les données XML en dehors de la logique de l'application. + +```xml + +<!-- Ci-dessous, vous pouvez voir une version simplifiée du document de librairie, + avec l'addition de définition DTD. --> + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE note SYSTEM "Librairie.dtd"> +<librairie> + <livre categorie="CUISINE"> + <titre>Everyday Italian</titre> + <prix>30.00</prix> + </livre> +</librairie> + +<!-- Cette DTD pourrait être quelque chose comme: --> + +<!DOCTYPE note +[ +<!ELEMENT librairie (livre+)> +<!ELEMENT livre (titre,prix)> +<!ATTLIST livre categorie CDATA "Littérature"> +<!ELEMENT titre (#PCDATA)> +<!ELEMENT prix (#PCDATA)> +]> + +<!-- La DTD commence par une déclaration. + Après, le nœud racine est déclaré, qui exige un ou plusieurs nœuds enfants. + Chaque «livre» doit contenir exactement un «titre» et «prix» et un attribut + appelé «catégorie», avec «littérature» comme valeur par défaut. + Les nœuds de «titre» et «prix» contiennent des informations de caractère analysés + (Anglais: «parsed character data») --> + +<!-- La DTD pourrait être déclarée dans le fichier XML lui-même --> + +<?xml version="1.0" encoding="UTF-8"?> + +<!DOCTYPE note +[ +<!ELEMENT librairie (livre+)> +<!ELEMENT livre (titre,prix)> +<!ATTLIST livre categorie CDATA "Littérature"> +<!ELEMENT titre (#PCDATA)> +<!ELEMENT prix (#PCDATA)> +]> + +<librairie> + <livre categorie="CUISINE"> + <titre>Everyday Italian</titre> + <prix>30.00</prix> + </livre> +</librairie> +``` diff --git a/haskell.html.markdown b/haskell.html.markdown index e0489710..ad12de2a 100644 --- a/haskell.html.markdown +++ b/haskell.html.markdown @@ -1,5 +1,5 @@ --- -language: haskell +language: Haskell contributors: - ["Adit Bhargava", "http://adit.io"] --- diff --git a/julia.html.markdown b/julia.html.markdown index feb38463..3a52018c 100644 --- a/julia.html.markdown +++ b/julia.html.markdown @@ -1,5 +1,5 @@ --- -language: julia +language: Julia contributors: - ["Leah Hanson", "http://leahhanson.us"] filename: learnjulia.jl diff --git a/ko-kr/lua-kr.html.markdown b/ko-kr/lua-kr.html.markdown index 850587a0..b4a018ef 100644 --- a/ko-kr/lua-kr.html.markdown +++ b/ko-kr/lua-kr.html.markdown @@ -1,5 +1,5 @@ --- -language: lua +language: Lua category: language contributors: - ["Tyler Neylon", "http://tylerneylon.com/"] diff --git a/ko-kr/php-kr.html.markdown b/ko-kr/php-kr.html.markdown index 80f324f3..1f53221f 100644 --- a/ko-kr/php-kr.html.markdown +++ b/ko-kr/php-kr.html.markdown @@ -1,5 +1,5 @@ --- -language: php +language: PHP category: language contributors: - ["Malcolm Fell", "http://emarref.net/"] diff --git a/lua.html.markdown b/lua.html.markdown index be9f3141..0809215f 100644 --- a/lua.html.markdown +++ b/lua.html.markdown @@ -1,5 +1,5 @@ --- -language: lua +language: Lua contributors: - ["Tyler Neylon", "http://tylerneylon.com/"] filename: learnlua.lua diff --git a/markdown.html.markdown b/markdown.html.markdown index 3d4d0af6..7541f904 100644 --- a/markdown.html.markdown +++ b/markdown.html.markdown @@ -126,6 +126,14 @@ render the numbers in order, but this may not be a good idea --> * Sub-item 4. Item four +<!-- There are even task lists. This creates HTML checkboxes. --> + +Boxes below without the 'x' are unchecked HTML checkboxes. +- [ ] First task to complete. +- [ ] Second task that needs done +This checkbox below will be a checked HTML checkbox. +- [x] This task has been completed + <!-- Code blocks --> <!-- You can indicate a code block (which uses the <code> element) by indenting a line with four spaces or a tab --> diff --git a/nl-nl/coffeescript-nl.html.markdown b/nl-nl/coffeescript-nl.html.markdown new file mode 100644 index 00000000..70dcd463 --- /dev/null +++ b/nl-nl/coffeescript-nl.html.markdown @@ -0,0 +1,109 @@ +--- +language: coffeescript +contributors: + - ["Tenor Biel", "http://github.com/L8D"] + - ["Xavier Yao", "http://github.com/xavieryao"] +translators: + - ["Jelle Besseling", "https://github.com/Jell-E"] +filename: coffeescript-nl.coffee +lang: nl-nl +--- + +CoffeeScript is een kleine programmeertaal die compileerd naar JavaScript, +er is geen interpretatie tijdens het uitvoeren. +Als een van de nakomelingen van JavaScript probeert CoffeeScript om leesbare, +goed geformatteerdeen goed draaiende JavaScript code te genereren, +die in elke JavaScript runtime werkt. + +Op [de CoffeeScript website](http://coffeescript.org/), staat een +vollediger tutorial voor CoffeeScript. + +``` coffeescript +# CoffeeScript is een taal voor hipsters. +# Het gaat mee met alle trends van moderne talen. +# Dus commentaar begint met een hekje, net zoals bij Python en Ruby. + +### +Blokken commentaar maak je zo, ze vertalen naar JavaScripts */ en /* +in de uitvoer van de CoffeeScript compiler. + +Het is belangrijk dat je ongeveer snapt hoe JavaScript +werkt voordat je verder gaat. +### + +# Toewijzing: +getal = 42 #=> var getal = 42; +tegengestelde = true #=> var tegengestelde = true; + +# Voorwaarden: +getal = -42 if tegengestelde #=> if(tegengestelde) { getal = -42; } + +# Functies: +kwadraat = (x) -> x * x #=> var kwadraat = function(x) { return x * x; } + +vul = (houder, vloeistof = "koffie") -> + "Nu de #{houder} met #{koffie} aan het vullen..." +#=>var vul; +# +#vul = function(houder, vloeistof) { +# if (vloeistof == null) { +# vloeistof = "coffee"; +# } +# return "Nu de " + houder + " met " + vloeistof + " aan het vullen..."; +#}; + +# Reeksen: +lijst = [1..5] #=> var lijst = [1, 2, 3, 4, 5]; + +# Objecten: +wiskunde = + wortel: Math.sqrt + kwadraat: kwadraat + derdemacht: (x) -> x * kwadraat x +#=> var wiskunde = { +# "wortel": Math.sqrt, +# "kwadraat": kwadraat, +# "derdemacht": function(x) { return x * kwadraat(x); } +#} + +# "Splats": +wedstrijd = (winnaar, lopers...) -> + print winnaar, lopers +#=>wedstrijd = function() { +# var lopers, winnaar; +# winnaar = arguments[0], lopers = 2 <= arguments.length ? __slice.call(arguments, 1) : []; +# return print(winnaar, lopers); +#}; + +# Bestaan: +alert "Ik wist het!" if elvis? +#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); } + +# Lijst abstractie: +derdemachten = (wiskunde.derdemacht num for num in lijst) +#=>derdemachten = (function() { +# var _i, _len, _results; +# _results = []; +# for (_i = 0, _len = lijst.length; _i < _len; _i++) { +# num = list[_i]; +# _results.push(wiskunde.derdemacht(num)); +# } +# return _results; +# })(); + +etenswaren = ['broccoli', 'spinazie', 'chocolade'] +eet eten for eten in etenswaren when eten isnt 'chocolade' +#=>etenswaren = ['broccoli', 'spinazie', 'chocolade']; +# +#for (_k = 0, _len2 = etenswaren.length; _k < _len2; _k++) { +# eten = etenswaren[_k]; +# if (eten !== 'chocolade') { +# eet(eten); +# } +#} +``` + +## Handige links (in het Engels): + +- [Smooth CoffeeScript](http://autotelicum.github.io/Smooth-CoffeeScript/) +- [CoffeeScript Ristretto](https://leanpub.com/coffeescript-ristretto/read) diff --git a/perl6.html.markdown b/perl6.html.markdown index 7afcc930..52625bc2 100644 --- a/perl6.html.markdown +++ b/perl6.html.markdown @@ -64,7 +64,7 @@ say "Interpolate an array using [] : @array[]"; my @keys = 0, 2; @array[@keys] = @letters; # Assign using an array -say @array; #=> a 2 b +say @array; #=> a 6 b # There are two more kinds of lists: Parcel and Arrays. # Parcels are immutable lists (you can't modify a list that's not assigned). @@ -1447,7 +1447,7 @@ so 'ayc' ~~ / a [ b | y ] c /; # `True`. Obviously enough ... # It's very powerful, because Perl 6 actually parses the argument # and pass them as such to the sub. It also handles named argument (`--foo`) # and will even go as far as to autogenerate a `--help` -sub MAIN($name) { say "Hello, you !" } +sub MAIN($name) { say "Hello, $name !" } # This produces: # $ perl6 cli.pl # Usage: diff --git a/php.html.markdown b/php.html.markdown index e1bb86a0..039288a0 100644 --- a/php.html.markdown +++ b/php.html.markdown @@ -1,5 +1,5 @@ --- -language: php +language: PHP contributors: - ["Malcolm Fell", "http://emarref.net/"] - ["Trismegiste", "https://github.com/Trismegiste"] diff --git a/pt-br/haskell-pt.html.markdown b/pt-br/haskell-pt.html.markdown index 55f90bd6..788dc1d2 100644 --- a/pt-br/haskell-pt.html.markdown +++ b/pt-br/haskell-pt.html.markdown @@ -1,5 +1,5 @@ --- -language: haskell +language: Haskell contributors: - ["Adit Bhargava", "http://adit.io"] translators: diff --git a/pt-br/php-pt.html.markdown b/pt-br/php-pt.html.markdown index 344df43a..0e710742 100644 --- a/pt-br/php-pt.html.markdown +++ b/pt-br/php-pt.html.markdown @@ -1,5 +1,5 @@ --- -language: php +language: PHP contributors: - ["Malcolm Fell", "http://emarref.net/"] - ["Trismegiste", "https://github.com/Trismegiste"] diff --git a/python.html.markdown b/python.html.markdown index 390c7b76..ba236fb3 100644 --- a/python.html.markdown +++ b/python.html.markdown @@ -3,6 +3,7 @@ language: python contributors: - ["Louie Dinh", "http://ldinh.ca"] - ["Amin Bandali", "http://aminbandali.com"] + - ["Andre Polykanine", "https://github.com/Oire"] filename: learnpython.py --- @@ -54,19 +55,22 @@ to Python 2.x. Look for another tour of Python 3 soon! # Modulo operation 7 % 3 # => 1 +# Exponentiation (x to the y'th power) +2**4 # => 16 + # Enforce precedence with parentheses (1 + 3) * 2 # => 8 # 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 +# 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 diff --git a/python3.html.markdown b/python3.html.markdown index a94f4eae..e478e57f 100644 --- a/python3.html.markdown +++ b/python3.html.markdown @@ -3,6 +3,7 @@ language: python3 contributors: - ["Louie Dinh", "http://pythonpracticeprojects.com"] - ["Steven Basart", "http://github.com/xksteven"] + - ["Andre Polykanine", "https://github.com/Oire"] filename: learnpython3.py --- @@ -50,6 +51,9 @@ Note: This article applies to Python 3 specifically. Check out the other tutoria # Modulo operation 7 % 3 # => 1 +# Exponentiation (x to the y'th power) +2**4 # => 16 + # Enforce precedence with parentheses (1 + 3) * 2 # => 8 diff --git a/ru-ru/coffeescript-ru.html.markdown b/ru-ru/coffeescript-ru.html.markdown new file mode 100644 index 00000000..f8416f38 --- /dev/null +++ b/ru-ru/coffeescript-ru.html.markdown @@ -0,0 +1,104 @@ +--- +language: coffeescript +contributors: + - ["Tenor Biel", "http://github.com/L8D"] + - ["Xavier Yao", "http://github.com/xavieryao"] +translators: + - ["asaskevich", "http://github.com/asaskevich"] +filename: learncoffee-ru.coffee +lang: ru-ru +--- + +CoffeeScript - это небольшой язык, который компилируется один-в-один в эквивалентный код на языке JavaScript, а потому он не интерпретируется во время исполнения JavaScript кода. +Ключевой особенностью CoffeeScript является то, что он пытается создать читабельный, качественно оформленный и плавный JavaScript код, прекрасно работающий в любой среде JavaScript. + +Также загляните на официальный сайт [языка](http://coffeescript.org/), где можно найти весьма полное учебное пособие по CoffeeScript. + +```coffeescript +# CoffeeScript - язык хипстеров. +# Язык использует самое модное из множества современных языков. +# Эти комментарии по стилю похожи на комментарии Ruby или Python, они используют "решетку" в качестве знака комментария. + +### +Блоки комментариев выделяются тремя символами "решетки", в результирующем JavaScript коде они будут преобразованы в '/ * и '* /'. + +Перед тем, как идти далее, Вам нужно понимать семантику JavaScript. +### + +# Присвоение: +number = 42 #=> var number = 42; +opposite = true #=> var opposite = true; + +# Условия: +number = -42 if opposite #=> if(opposite) { number = -42; } + +# Функции: +square = (x) -> x * x #=> var square = function(x) { return x * x; } + +fill = (container, liquid = "coffee") -> + "Заполняем #{container} жидкостью #{liquid}..." +#=>var fill; +# +#fill = function(container, liquid) { +# if (liquid == null) { +# liquid = "coffee"; +# } +# return "Заполняем " + container + " жидкостью " + liquid + "..."; +#}; + +# Списки и диапазоны: +list = [1..5] #=> var list = [1, 2, 3, 4, 5]; + +# Объекты: +math = + root: Math.sqrt + square: square + cube: (x) -> x * square x +#=> var math = { +# "root": Math.sqrt, +# "square": square, +# "cube": function(x) { return x * square(x); } +#} + +# Многоточия: +race = (winner, runners...) -> + print winner, runners +#=>race = function() { +# var runners, winner; +# winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : []; +# return print(winner, runners); +#}; + +# Проверка на существование объекта: +alert "Так и знал!" if elvis? +#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("Так и знал!"); } + +# Итерации по массивам: +cubes = (math.cube num for num in list) +#=>cubes = (function() { +# var _i, _len, _results; +# _results = []; +# for (_i = 0, _len = list.length; _i < _len; _i++) { +# num = list[_i]; +# _results.push(math.cube(num)); +# } +# return _results; +# })(); + +foods = ['broccoli', 'spinach', 'chocolate'] +eat food for food in foods when food isnt 'chocolate' +#=>foods = ['broccoli', 'spinach', 'chocolate']; +# +#for (_k = 0, _len2 = foods.length; _k < _len2; _k++) { +# food = foods[_k]; +# if (food !== 'chocolate') { +# eat(food); +# } +#} +``` + +## На почитать + +- [Smooth CoffeeScript](http://autotelicum.github.io/Smooth-CoffeeScript/) +- [CoffeeScript Ristretto](https://leanpub.com/coffeescript-ristretto/read) +- [CoffeeScript на русском](http://cidocs.ru/coffeescript/) diff --git a/ru-ru/haskell-ru.html.markdown b/ru-ru/haskell-ru.html.markdown index 03e66d05..e15fe6b7 100644 --- a/ru-ru/haskell-ru.html.markdown +++ b/ru-ru/haskell-ru.html.markdown @@ -1,5 +1,5 @@ --- -language: haskell +language: Haskell contributors: - ["Adit Bhargava", "http://adit.io"] translators: diff --git a/ru-ru/julia-ru.html.markdown b/ru-ru/julia-ru.html.markdown index cd55e116..29392604 100644 --- a/ru-ru/julia-ru.html.markdown +++ b/ru-ru/julia-ru.html.markdown @@ -1,5 +1,5 @@ --- -language: julia +language: Julia contributors: - ["Leah Hanson", "http://leahhanson.us"] translators: diff --git a/ru-ru/php-ru.html.markdown b/ru-ru/php-ru.html.markdown index edcac4dd..53b2f916 100644 --- a/ru-ru/php-ru.html.markdown +++ b/ru-ru/php-ru.html.markdown @@ -1,5 +1,5 @@ --- -language: php +language: PHP contributors: - ["Malcolm Fell", "http://emarref.net/"] - ["Trismegiste", "https://github.com/Trismegiste"] diff --git a/ru-ru/python3-ru.html.markdown b/ru-ru/python3-ru.html.markdown new file mode 100644 index 00000000..637c0157 --- /dev/null +++ b/ru-ru/python3-ru.html.markdown @@ -0,0 +1,630 @@ +--- +language: python3 +lang: ru-ru +contributors: + - ["Louie Dinh", "http://ldinh.ca"] + - ["Steven Basart", "http://github.com/xksteven"] +translators: + - ["Andre Polykanine", "https://github.com/Oire"] +filename: learnpython3-ru.py +--- + +Язык Python был создан Гвидо ван Россумом в начале 90-х. Сейчас это один из +самых популярных языков. Я люблю его за понятный и доходчивый синтаксис — это +почти что исполняемый псевдокод. + +С благодарностью жду ваших отзывов: [@louiedinh](http://twitter.com/louiedinh) +или louiedinh [at] [почтовый сервис Google] + +Замечание: Эта статья относится только к Python 3. +Если вы хотите изучить Python 2.7, обратитесь к другой статье. + +```python +# Однострочные комментарии начинаются с символа решётки. +""" Многострочный текст может быть + записан, используя 3 знака " и обычно используется + в качестве встроенной документации +""" + +#################################################### +## 1. Примитивные типы данных и операторы +#################################################### + +# У вас есть числа +3 #=> 3 + +# Математика работает вполне ожидаемо +1 + 1 #=> 2 +8 - 1 #=> 7 +10 * 2 #=> 20 + +# Кроме деления, которое по умолчанию возвращает число с плавающей запятой +35 / 5 # => 7.0 + +# Результат целочисленного деления округляется в меньшую сторону +# как для положительных, так и для отрицательных чисел. +5 // 3 # => 1 +5.0 // 3.0 # => 1.0 # работает и для чисел с плавающей запятой +-5 // 3 # => -2 +-5.0 // 3.0 # => -2.0 + +# Когда вы используете числа с плавающей запятой, +# результатом будет также число с плавающей запятой +3 * 2.0 # => 6.0 + +# Остаток от деления +7 % 3 # => 1 + +# Возведение в степень +2 ** 4 # => 16 + +# Приоритет операций указывается скобками +(1 + 3) * 2 #=> 8 + +# Для логических (булевых) значений существует отдельный примитивный тип +True +False + +# Для отрицания используется ключевое слово not +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 +2 >= 2 #=> True + +# Сравнения могут быть записаны цепочкой: +1 < 2 < 3 #=> True +2 < 3 < 2 #=> False + +# Строки определяются символом " или ' +"Это строка." +'Это тоже строка.' + +# И строки тоже могут складываться! Хотя лучше этого не делайте. +"Привет " + "мир!" #=> "Привет мир!" + +# Со строкой можно работать, как со списком символов +"Это строка"[0] #=> 'Э' + +# Метод format используется для форматирования строк: +"{0} могут быть {1}".format("строки", "форматированы") + +# Вы можете повторять аргументы форматирования, чтобы меньше печатать. +"Ехал {0} через реку, видит {0} - в реке {1}! Сунул {0} руку в реку, {1} за руку греку цап!".format("грека", "рак") +#=> "Ехал грека через реку, видит грека - в реке рак! Сунул грека руку в реку, рак за руку греку цап!" +# Если вы не хотите считать, можете использовать ключевые слова. +"{name} хочет есть {food}".format(name="Боб", food="лазанью") + +# Если ваш код на Python 3 нужно запускать также и под Python 2.5 и ниже, +# вы также можете использовать старый способ форматирования: +"%s можно %s %s способом" % ("строки", "интерполировать", "старым") + +# None является объектом +None #=> None + +# Не используйте оператор равенства '==' для сравнения +# объектов с None. Используйте для этого 'is' +"etc" is None #=> False +None is None #=> True + +# Оператор «is» проверяет идентичность объектов. Он не +# очень полезен при работе с примитивными типами, но +# зато просто незаменим при работе с объектами. + +# None, 0 и пустые строки/списки/словари приводятся к False. +# Все остальные значения равны True +bool(0) # => False +bool("") # => False +bool([]) #=> False +bool({}) #=> False + + +#################################################### +## 2. Переменные и коллекции +#################################################### + +# У Python есть функция Print +print("Я Python. Приятно познакомиться!") + +# Необязательно объявлять переменные перед их инициализацией. +# По соглашению используется нижний_регистр_с_подчёркиваниями +some_var = 5 +some_var #=> 5 + +# При попытке доступа к неинициализированной переменной +# выбрасывается исключение. +# Об исключениях см. раздел «Поток управления и итерируемые объекты». +some_unknown_var # Выбрасывает ошибку именования + +# Списки хранят последовательности +li = [] +# Можно сразу начать с заполненным списком +other_li = [4, 5, 6] + +# Объекты добавляются в конец списка методом append +li.append(1) # [1] +li.append(2) # [1, 2] +li.append(4) # [1, 2, 4] +li.append(3) # [1, 2, 4, 3] +# И удаляются с конца методом pop +li.pop() #=> возвращает 3 и li становится равен [1, 2, 4] +# Положим элемент обратно +li.append(3) # [1, 2, 4, 3]. + +# Обращайтесь со списком, как с обычным массивом +li[0] #=> 1 +# Обратимся к последнему элементу +li[-1] #=> 3 + +# Попытка выйти за границы массива приведёт к ошибке индекса +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 не изменяются + +# Объединять списки можно методом extend +li.extend(other_li) # Теперь li содержит [1, 2, 3, 4, 5, 6] + +# Проверить элемент на вхождение в список можно оператором in +1 in li #=> True + +# Длина списка вычисляется функцией len +len(li) #=> 6 + + +# Кортежи — это такие списки, только неизменяемые +tup = (1, 2, 3) +tup[0] #=> 1 +tup[0] = 3 # Выдаёт TypeError + +# Всё то же самое можно делать и с кортежами +len(tup) #=> 3 +tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6) +tup[:2] #=> (1, 2) +2 in tup #=> True + +# Вы можете распаковывать кортежи (или списки) в переменные +a, b, c = (1, 2, 3) # a == 1, b == 2 и c == 3 +# Кортежи создаются по умолчанию, если опущены скобки +d, e, f = 4, 5, 6 +# Обратите внимание, как легко поменять местами значения двух переменных +e, d = d, e # теперь d == 5, а e == 4 + + +# Словари содержат ассоциативные массивы +empty_dict = {} +# Вот так описывается предзаполненный словарь +filled_dict = {"one": 1, "two": 2, "three": 3} + +# Значения ищутся по ключу с помощью оператора [] +filled_dict["one"] #=> 1 + +# Все значения в виде списка получаются с помощью метода keys(). +# Его вызов нужно обернуть в list(), так как обратно мы получаем +# итерируемый объект, о которых поговорим позднее. +list(filled_dict.keys()) # => ["three", "two", "one"] +# Замечание: сохранение порядка ключей в словаре не гарантируется +# Ваши результаты могут не совпадать с этими. + +# Все значения в виде списка можно получить с помощью values(). +# И снова нам нужно обернуть вызов в list(), чтобы превратить +# итерируемый объект в список. +list(filled_dict.values()) # => [3, 2, 1] +# То же самое замечание насчёт порядка ключей справедливо и здесь + +# При помощи оператора in можно проверять ключи на вхождение в словарь +"one" in filled_dict #=> True +1 in filled_dict #=> False + +# Попытка получить значение по несуществующему ключу выбросит ошибку ключа +filled_dict["four"] # KeyError + +# Чтобы избежать этого, используйте метод get +filled_dict.get("one") #=> 1 +filled_dict.get("four") #=> None +# Метод get также принимает аргумент по умолчанию, значение которого будет +# возвращено при отсутствии указанного ключа +filled_dict.get("one", 4) #=> 1 +filled_dict.get("four", 4) #=> 4 + +# Метод setdefault вставляет пару ключ-значение, только если такого ключа нет +filled_dict.setdefault("five", 5) #filled_dict["five"] возвращает 5 +filled_dict.setdefault("five", 6) #filled_dict["five"] по-прежнему возвращает 5 + +# Удаляйте ключи из словаря с помощью оператора del +del filled_dict["one"] # Удаляет ключ «one» из словаря + + +# Множества содержат... ну, в общем, множества +empty_set = set() +# Инициализация множества набором значений. +# Да, оно выглядит примерно как словарь… ну извините, так уж вышло. +filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4} + +# Множеству можно назначать новую переменную +filled_set = some_set + +# Добавление новых элементов в множество +filled_set.add(5) # filled_set равно {1, 2, 3, 4, 5} + +# Пересечение множеств: & +other_set = {3, 4, 5, 6} +filled_set & other_set #=> {3, 4, 5} + +# Объединение множеств: | +filled_set | other_set #=> {1, 2, 3, 4, 5, 6} + +# Разность множеств: - +{1,2,3,4} - {2,3,5} #=> {1, 4} + +# Проверка на вхождение во множество: in +2 in filled_set #=> True +10 in filled_set #=> False + + +#################################################### +## 3. Поток управления и итерируемые объекты +#################################################### + +# Для начала заведём переменную +some_var = 5 + +# Так выглядит выражение if. Отступы в python очень важны! +# результат: «some_var меньше, чем 10» +if some_var > 10: + print("some_var намного больше, чем 10.") +elif some_var < 10: # Выражение elif необязательно. + print("some_var меньше, чем 10.") +else: # Это тоже необязательно. + print("some_var равно 10.") + + +# Циклы For проходят по спискам. Результат: + # собака — это млекопитающее + # кошка — это млекопитающее + # мышь — это млекопитающее +for animal in ["собака", "кошка", "мышь"]: + # Можете использовать format() для интерполяции форматированных строк + print("{} — это млекопитающее".format(animal)) + +""" +«range(число)» возвращает список чисел +от нуля до заданного числа +Результат: + 0 + 1 + 2 + 3 +""" +for i in range(4): + print(i) + +""" +Циклы while продолжаются до тех пор, пока указанное условие не станет ложным. +Результат: + 0 + 1 + 2 + 3 +""" +x = 0 +while x < 4: + print(x) + x += 1 # Краткая запись для x = x + 1 + +# Обрабатывайте исключения блоками try/except +try: + # Чтобы выбросить ошибку, используется raise + raise IndexError("Это ошибка индекса") +except IndexError as e: + # pass это просто отсутствие оператора. Обычно здесь происходит + # восстановление после ошибки. + pass +except (TypeError, NameError): + pass # Несколько исключений можно обработать вместе, если нужно. +else: # Необязательное выражение. Должно следовать за последним блоком except + print("Всё хорошо!") # Выполнится, только если не было никаких исключений + +# Python предоставляет фундаментальную абстракцию, +# которая называется итерируемым объектом (an iterable). +# Итерируемый объект — это объект, который воспринимается как последовательность. +# Объект, который возвратила функция range(), итерируемый. +filled_dict = {"one": 1, "two": 2, "three": 3} +our_iterable = filled_dict.keys() +print(our_iterable) #=> range(1,10). Это объект, реализующий интерфейс iterable + +# Мы можем проходить по нему циклом. +for i in our_iterable: + print(i) # Выводит one, two, three + +# Но мы не можем обращаться к элементу по индексу. +our_iterable[1] # Выбрасывает ошибку типа + +# Итерируемый объект знает, как создавать итератор. +our_iterator = iter(our_iterable) + +# Итератор может запоминать состояние при проходе по объекту. +# Мы получаем следующий объект, вызывая функцию __next__. +our_iterator.__next__() #=> "one" + +# Он сохраняет состояние при вызове __next__. +our_iterator.__next__() #=> "two" +our_iterator.__next__() #=> "three" + +# Возвратив все данные, итератор выбрасывает исключение StopIterator +our_iterator.__next__() # Выбрасывает исключение остановки итератора + +# Вы можете получить сразу все элементы итератора, вызвав на нём функцию list(). +list(filled_dict.keys()) #=> Возвращает ["one", "two", "three"] + + +#################################################### +## 4. Функции +#################################################### + +# Используйте def для создания новых функций +def add(x, y): + print("x равен %s, а y равен %s" % (x, y)) + return x + y # Возвращайте результат выражением return + +# Вызов функции с аргументами +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 + +# Вызовем эту функцию и посмотрим, что из этого получится +keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"} + +# Если хотите, можете использовать оба способа одновременно +def all_the_args(*args, **kwargs): + print(args) + print(kwargs) +""" +all_the_args(1, 2, a=3, b=4) выводит: + (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) + +# Область определения функций +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 + return adder + +add_10 = create_adder(10) +add_10(3) #=> 13 + +# Также есть и анонимные функции +(lambda x: x > 2)(3) #=> True + +# Есть встроенные функции высшего порядка +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] + +#################################################### +## 5. Классы +#################################################### + +# Чтобы получить класс, мы наследуемся от object. +class Human(object): + + # Атрибут класса. Он разделяется всеми экземплярами этого класса + species = "H. sapiens" + + # Обычный конструктор, вызывается при инициализации экземпляра класса + # Обратите внимание, что двойное подчёркивание в начале и в конце имени + # означает объекты и атрибуты, которые используются Python, но находятся + # в пространствах имён, управляемых пользователем. + # Не придумывайте им имена самостоятельно. + def __init__(self, name): + # Присваивание значения аргумента атрибуту класса name + self.name = name + + # Метод экземпляра. Все методы принимают self в качестве первого аргумента + def say(self, msg): + return "{name}: {message}".format(name=self.name, message=msg) + + # Метод класса разделяется между всеми экземплярами + # Они вызываются с указыванием вызывающего класса в качестве первого аргумента + @classmethod + def get_species(cls): + return cls.species + + # Статический метод вызывается без ссылки на класс или экземпляр + @staticmethod + def grunt(): + return "*grunt*" + + +# Инициализация экземпляра класса +i = Human(name="Иван") +print(i.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" + +# Вызов статического метода +Human.grunt() #=> "*grunt*" + + +#################################################### +## 6. Модули +#################################################### + +# Вы можете импортировать модули +import math +print(math.sqrt(16)) #=> 4 + +# Вы можете импортировать отдельные функции модуля +from math import ceil, floor +print(ceil(3.7)) #=> 4.0 +print(floor(3.7)) #=> 3.0 + +# Можете импортировать все функции модуля. +# (Хотя это и не рекомендуется) +from math import * + +# Можете сокращать имена модулей +import math as m +math.sqrt(16) == m.sqrt(16) #=> True + +# Модули в Python — это обычные Python-файлы. Вы +# можете писать свои модули и импортировать их. Название +# модуля совпадает с названием файла. + +# Вы можете узнать, какие функции и атрибуты определены +# в модуле +import math +dir(math) + +#################################################### +## 7. Дополнительно +#################################################### + +# Генераторы помогут выполнить ленивые вычисления +def double_numbers(iterable): + for i in iterable: + yield i + i + +# Генератор создаёт значения на лету. +# Он не возвращает все значения разом, а создаёт каждое из них при каждой +# итерации. Это значит, что значения больше 15 в double_numbers +# обработаны не будут. +# Обратите внимание: range — это тоже генератор. +# Создание списка чисел от 1 до 900000000 требует много места и времени. +# Если нам нужно имя переменной, совпадающее с ключевым словом Python, +# мы используем подчёркивание в конце +range_ = range(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/) +* [Ideas for Python Projects](http://pythonpracticeprojects.com) +* [Официальная документация](http://docs.python.org/3/) +* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/) +* [Python Module of the Week](http://pymotw.com/3/) +* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182) + +### Платные + +* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20) +* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20) +* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20) + diff --git a/rust.html.markdown b/rust.html.markdown index 0b9a5e58..3717a7d9 100644 --- a/rust.html.markdown +++ b/rust.html.markdown @@ -255,8 +255,8 @@ fn main() { ## Further reading There’s a lot more to Rust—this is just the basics of Rust so you can -understand the most important things. To learn more about Rust, read the -[Rust tutorial](http://doc.rust-lang.org/tutorial.html) and check out the +understand the most important things. To learn more about Rust, read [The Rust +Guide](http://doc.rust-lang.org/guide.html) and check out the [/r/rust](http://reddit.com/r/rust) subreddit. The folks on the #rust channel on irc.mozilla.org are also always keen to help newcomers. diff --git a/tmux.html.markdown b/tmux.html.markdown index 8d7aa752..ebc312ed 100644 --- a/tmux.html.markdown +++ b/tmux.html.markdown @@ -2,22 +2,23 @@ category: tool tool: tmux contributors: - - ["kaernyk", "http://github.com/kaernyk"] + - ["kaernyk", "https://github.com/kaernyk"] + - ["jmaud", "https://github.com/jmaud"] 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 +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 + # 'tmux' with no commands will create a new session new # Create a new session -s "Session" # Create named session @@ -54,7 +55,7 @@ then later reattached. ## Key Bindings -# The method of controlling an attached tmux session is via key +# The method of controlling an attached tmux session is via key # combinations called 'Prefix' keys. ---------------------------------------------------------------------- @@ -63,47 +64,48 @@ then later reattached. (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 + ? # 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 + ! # 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 + 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 + s # Select a new session for the attached client interactively - w # Choose the current window interactively - 0 to 9 # Select windows 0 to 9 + 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 + d # Detach the current client + D # Choose a client to detach - & # Kill the current window - x # Kill the current pane + & # Kill the current window + x # Kill the current pane - Up, Down # Change to the pane above, below, left, or right - Left, Right + 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 + 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 + 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 + M-Up, M-Down # Resize the current pane in steps of five cells + M-Left, M-Right +``` ### Configuring ~/.tmux.conf @@ -111,30 +113,59 @@ then later reattached. 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 +# 2014.10 + + +### General +########################################################################### + +# Enable UTF-8 +setw -g utf8 on +set-option -g status-utf8 on + +# Scrollback/History limit +set -g history-limit 2048 + +# Index Start +set -g base-index 1 + +# Mouse +set-option -g mouse-select-pane on + +# Force reload of config file +unbind r +bind r source-file ~/.tmux.conf ### Keybinds -###################################################################### +########################################################################### # Unbind C-b as the default prefix -unbind-key C-befix C-a +unbind C-b + +# Set new default prefix +set-option -g prefix ` # Return to previous window when prefix is pressed twice -bind-key C-a last-window -bind-key ` last-window +bind C-a last-window +bind ` 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 ` +bind F11 set-option -g prefix C-a +bind F12 set-option -g prefix ` -# Activate inner-most session (when nesting tmux) -# to send commands -bind-key a send-prefix +# Keybind preference +setw -g mode-keys vi +set-option -g status-keys vi -# Index Start -set -g base-index 1 +# 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 # Window Cycle/Swap bind e previous-window @@ -142,23 +173,20 @@ 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 +# Easy 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 +# Activate inner-most session (when nesting tmux) to send commands +bind a send-prefix ### Theme -##################################################################### +########################################################################### -# Statusbar Color Palette +# Statusbar Color Palatte set-option -g status-justify left set-option -g status-bg black set-option -g status-fg white @@ -187,14 +215,7 @@ 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 @@ -202,41 +223,20 @@ 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' +set-option -g set-titles-string '#H:#S.#I.#P #W #T' # window number,program name,active (or not) # 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]' +set -g status-left "#[fg=red] #H#[fg=green]:#[fg=white]#S#[fg=green] |#[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]' +set -g status-interval 4 +set -g status-right "#[fg=green] | #[fg=white]#(tmux-mem-cpu-load)#[fg=green] | #[fg=cyan]%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> diff --git a/tr-tr/php-tr.html.markdown b/tr-tr/php-tr.html.markdown index 3db437cf..5258d785 100644 --- a/tr-tr/php-tr.html.markdown +++ b/tr-tr/php-tr.html.markdown @@ -1,5 +1,5 @@ --- -language: php +language: PHP filename: learnphp-tr.php contributors: - ["Malcolm Fell", "http://emarref.net/"] diff --git a/zh-cn/c-cn.html.markdown b/zh-cn/c-cn.html.markdown index 223f6e35..1e10416e 100644 --- a/zh-cn/c-cn.html.markdown +++ b/zh-cn/c-cn.html.markdown @@ -566,7 +566,7 @@ typedef void (*my_fnp_type)(char *); '\'' // 单引号 '\"' // 双引号 '\xhh' // 十六进制数字. 例子: '\xb' = vertical tab -'\ooo' // 十进制数字. 例子: '\013' = vertical tab +'\ooo' // 八进制数字. 例子: '\013' = vertical tab // 打印格式: "%d" // 整数 @@ -579,7 +579,7 @@ typedef void (*my_fnp_type)(char *); "%c" // 字母 "%p" // 指针 "%x" // 十六进制 -"%o" // 十进制 +"%o" // 八进制 "%%" // 打印 % /////////////////////////////////////// diff --git a/zh-cn/haskell-cn.html.markdown b/zh-cn/haskell-cn.html.markdown index 8d51f144..cb7ccdee 100644 --- a/zh-cn/haskell-cn.html.markdown +++ b/zh-cn/haskell-cn.html.markdown @@ -1,5 +1,5 @@ --- -language: haskell +language: Haskell filename: learn-haskell-zh.hs contributors: - ["Adit Bhargava", "http://adit.io"] diff --git a/zh-cn/julia-cn.html.markdown b/zh-cn/julia-cn.html.markdown index 7afc9043..1f91d52c 100644 --- a/zh-cn/julia-cn.html.markdown +++ b/zh-cn/julia-cn.html.markdown @@ -1,5 +1,5 @@ --- -language: julia +language: Julia filename: learn-julia-zh.jl contributors: - ["Jichao Ouyang", "http://oyanglul.us"] diff --git a/zh-cn/livescript-cn.html.markdown b/zh-cn/livescript-cn.html.markdown new file mode 100644 index 00000000..fea00bc1 --- /dev/null +++ b/zh-cn/livescript-cn.html.markdown @@ -0,0 +1,322 @@ +--- +language: LiveScript +filename: learnLivescript.ls +contributors: + - ["Christina Whyte", "http://github.com/kurisuwhyte/"] +translators: + - ["ShengDa Lyu", "http://github.com/SDLyu/"] +lang: zh-cn +--- + +LiveScript 是一种具有函数式特性且编译成 JavaScript 的语言,能对应 JavaScript 的基本语法。 +还有些额外的特性如:柯里化,组合函数,模式匹配,还有借镜于 Haskell,F# 和 Scala 的许多特点。 + +LiveScript 诞生于 [Coco][],而 Coco 诞生于 [CoffeeScript][]。 +LiveScript 目前已释出稳定版本,开发中的新版本将会加入更多特性。 + +[Coco]: http://satyr.github.io/coco/ +[CoffeeScript]: http://coffeescript.org/ + +非常期待您的反馈,你可以通过 +[@kurisuwhyte](https://twitter.com/kurisuwhyte) 与我连系 :) + + +```coffeescript +# 与 CoffeeScript 一样,LiveScript 使用 # 单行注解。 + +/* + 多行注解与 C 相同。使用注解可以避免被当成 JavaScript 输出。 +*/ +``` +```coffeescript +# 语法的部份,LiveScript 使用缩进取代 {} 来定义区块, +# 使用空白取代 () 来执行函数。 + + +######################################################################## +## 1. 值类型 +######################################################################## + +# `void` 取代 `undefined` 表示未定义的值 +void # 与 `undefined` 等价但更安全(不会被覆写) + +# 空值则表示成 Null。 +null + + +# 最基本的值类型数据是罗辑类型: +true +false + +# 罗辑类型的一些别名,等价于前者: +on; off +yes; no + + +# 数字与 JS 一样,使用倍精度浮点数表示。 +10 +0.4 # 开头的 0 是必要的 + + +# 可以使用底线及单位后缀提高可读性,编译器会自动略过底线及单位后缀。 +12_344km + + +# 字串与 JS 一样,是一种不可变的字元序列: +"Christina" # 单引号也可以! +"""Multi-line + strings + are + okay + too.""" + +# 在前面加上 \ 符号也可以表示字串: +\keyword # => 'keyword' + + +# 数组是值的有序集合。 +fruits = + * \apple + * \orange + * \pear + +# 可以用 [] 简洁地表示数组: +fruits = [ \apple, \orange, \pear ] + + +# 你可以更方便地建立字串数组,并使用空白区隔元素。 +fruits = <[ apple orange pear ]> + +# 以 0 为起始值的数组下标获取元素: +fruits[0] # => "apple" + + +# 对象是无序键值对集合(更多给节将在下面章节讨论)。 +person = + name: "Christina" + likes: + * "kittens" + * "and other cute stuff" + +# 你也可以用更简洁的方式表示对象: +person = {name: "Christina", likes: ["kittens", "and other cute stuff"]} + +# 可以通过键值获取值: +person.name # => "Christina" +person["name"] # => "Christina" + + +# 正则表达式的使用跟 JavaScript 一样: +trailing-space = /\s$/ # dashed-words 变成 dashedWords + +# 你也可以用多行描述表达式!(注解和空白会被忽略) +funRE = // + function\s+(.+) # name + \s* \((.*)\) \s* # arguments + { (.*) } # body + // + + +######################################################################## +## 2. 基本运算 +######################################################################## + +# 数值操作符与 JavaScript 一样: +1 + 2 # => 3 +2 - 1 # => 1 +2 * 3 # => 6 +4 / 2 # => 2 +3 % 2 # => 1 + + +# 比较操作符大部份也一样,除了 `==` 等价于 JS 中的 `===`, +# JS 中的 `==` 在 LiveScript 里等价于 `~=`, +# `===` 能进行对象、数组和严格比较。 +2 == 2 # => true +2 == "2" # => false +2 ~= "2" # => true +2 === "2" # => false + +[1,2,3] == [1,2,3] # => false +[1,2,3] === [1,2,3] # => true + ++0 == -0 # => true ++0 === -0 # => false + +# 其它关系操作符包括 <、<=、> 和 >= + +# 罗辑值可以通过 `or`、`and` 和 `not` 结合: +true and false # => false +false or true # => true +not false # => true + + +# 集合也有一些便利的操作符 +[1, 2] ++ [3, 4] # => [1, 2, 3, 4] +'a' in <[ a b c ]> # => true +'name' of { name: 'Chris' } # => true + + +######################################################################## +## 3. 函数 +######################################################################## + +# 因为 LiveScript 是函数式特性的语言,你可以期待函数在语言里被高规格的对待。 +add = (left, right) -> left + right +add 1, 2 # => 3 + +# 加上 ! 防止函数执行后的返回值 +two = -> 2 +two! + +# LiveScript 与 JavaScript 一样使用函式作用域,且一样拥有闭包的特性。 +# 与 JavaScript 不同的地方在于,`=` 变量赋值时,左边的对象永远不用变量宣告。 + +# `:=` 操作符允许*重新賦值*父作用域里的变量。 + + +# 你可以解构函数的参数,从不定长度的参数结构里获取感兴趣的值。 +tail = ([head, ...rest]) -> rest +tail [1, 2, 3] # => [2, 3] + +# 你也可以使用一元或二元操作符转换参数。当然也可以预设传入的参数值。 +foo = (a = 1, b = 2) -> a + b +foo! # => 3 + +# 你可以以拷贝的方式传入参数来避免副作用,例如: +copy = (^^target, source) -> + for k,v of source => target[k] = v + target +a = { a: 1 } +copy a, { b: 2 } # => { a: 1, b: 2 } +a # => { a: 1 } + + +# 使用长箭号取代短箭号来柯里化一个函数: +add = (left, right) --> left + right +add1 = add 1 +add1 2 # => 3 + +# 函式里有一个隐式的 `it` 变量,意谓着你不用宣告它。 +identity = -> it +identity 1 # => 1 + +# 操作符在 LiveScript 里不是一個函数,但你可以简单地将它们转换成函数! +# Enter the operator sectioning: +divide-by-2 = (/ 2) +[2, 4, 8, 16].map(divide-by-2) .reduce (+) + + +# LiveScript 里不只有应用函数,如同其它良好的函数式语言,你可以合并函数获得更多发挥: +double-minus-one = (- 1) . (* 2) + +# 除了普通的数学公式合并 `f . g` 之外,还有 `>>` 和 `<<` 操作符定义函数的合并顺序。 +double-minus-one = (* 2) >> (- 1) +double-minus-one = (- 1) << (* 2) + + +# 说到合并函数的参数, LiveScript 使用 `|>` 和 `<|` 操作符将参数传入: +map = (f, xs) --> xs.map f +[1 2 3] |> map (* 2) # => [2 4 6] + +# 你也可以选择填入值的位置,只需要使用底线 _ 标记: +reduce = (f, xs, initial) --> xs.reduce f, initial +[1 2 3] |> reduce (+), _, 0 # => 6 + + +# 你也能使 _ 让任何函数变成偏函数应用: +div = (left, right) -> left / right +div-by-2 = div _, 2 +div-by-2 4 # => 2 + + +# 最后,也很重要的,LiveScript 拥有後呼叫特性, 可以是基於回调的代码 +# (你可以试试其它函数式特性的解法,比如 Promises): +readFile = (name, f) -> f name +a <- readFile 'foo' +b <- readFile 'bar' +console.log a + b + +# 等同於: +readFile 'foo', (a) -> readFile 'bar', (b) -> console.log a + b + + +######################################################################## +## 4. 模式、判断和流程控制 +######################################################################## + +# 流程控制可以使用 `if...else` 表达式: +x = if n > 0 then \positive else \negative + +# 除了 `then` 你也可以使用 `=>` +x = if n > 0 => \positive + else \negative + +# 过於复杂的流程可以用 `switch` 表达式代替: +y = {} +x = switch + | (typeof y) is \number => \number + | (typeof y) is \string => \string + | 'length' of y => \array + | otherwise => \object # `otherwise` 和 `_` 是等价的。 + +# 函数主体、宣告式和赋值式可以表式成 `switch`,这可以省去一些代码: +take = (n, [x, ...xs]) --> + | n == 0 => [] + | _ => [x] ++ take (n - 1), xs + + +######################################################################## +## 5. 推导式 +######################################################################## + +# 在 JavaScript 的标准函式库里有一些辅助函数能帮助处理列表及对象 +#(LiveScript 则带有一个 prelude.ls ,作为标准函式库的补充 ), +# 推导式能让你使用优雅的语法且快速地处理这些事: +oneToTwenty = [1 to 20] +evens = [x for x in oneToTwenty when x % 2 == 0] + +# 在推导式里 `when` 和 `unless` 可以当成过滤器使用。 + +# 对象推导式在使用上也是同样的方式,差别在于你使用的是对象而不是数组: +copy = { [k, v] for k, v of source } + + +######################################################################## +## 6. OOP +######################################################################## + +# 虽然 LiveScript 是一门函数式语言,但具有一些命令式及面向对象的特性。 +# 像是 class 语法和一些借镜於 CoffeeScript 的类别继承语法糖: +class Animal + (@name, kind) -> + @kind = kind + action: (what) -> "*#{@name} (a #{@kind}) #{what}*" + +class Cat extends Animal + (@name) -> super @name, 'cat' + purr: -> @action 'purrs' + +kitten = new Cat 'Mei' +kitten.purr! # => "*Mei (a cat) purrs*" + +# 除了类别的单一继承模式之外,还提供了像混入 (Mixins) 这种特性。 +# Mixins 在语言里被当成普通对象: +Huggable = + hug: -> @action 'is hugged' + +class SnugglyCat extends Cat implements Huggable + +kitten = new SnugglyCat 'Purr' +kitten.hug! # => "*Mei (a cat) is hugged*" +``` + +## 延伸阅读 + +LiveScript 还有许多强大之处,但这些应该足够启发你写些小型函数式程式了。 +[LiveScript](http://livescript.net/)有更多关于 LiveScript 的资讯 +和线上编译器等着你来试! + +你也可以参考 +[prelude.ls](http://gkz.github.io/prelude-ls/),和一些 `#livescript` +的网络聊天室频道。 diff --git a/zh-cn/lua-cn.html.markdown b/zh-cn/lua-cn.html.markdown index 3ba098ec..53a603a2 100644 --- a/zh-cn/lua-cn.html.markdown +++ b/zh-cn/lua-cn.html.markdown @@ -1,5 +1,5 @@ --- -language: lua +language: Lua lang: zh-cn contributors: - ["Tyler Neylon", "http://tylerneylon.com/"] diff --git a/zh-cn/php-cn.html.markdown b/zh-cn/php-cn.html.markdown index 24939681..2def7f1c 100644 --- a/zh-cn/php-cn.html.markdown +++ b/zh-cn/php-cn.html.markdown @@ -1,5 +1,5 @@ --- -language: php +language: PHP contributors: - ["Malcolm Fell", "http://emarref.net/"] - ["Trismegiste", "https://github.com/Trismegiste"] |