diff options
61 files changed, 6843 insertions, 411 deletions
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..022dedab --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,6 @@ +Make sure the issue title is prepended with '[language/lang-code]' if the language is +already on the site. +If it's a request for a new language, use: '[Request] [language/lang-code]' + +Issues are always welcome. If you are able and willing, we welcome any pull requests +as this is a community powered project. diff --git a/angularjs.html.markdown b/angularjs.html.markdown index 89afa291..737b99c7 100644 --- a/angularjs.html.markdown +++ b/angularjs.html.markdown @@ -53,7 +53,7 @@ Before you study AngularJS, you should have a basic understanding of: * The ng-model directive binds the value of the input field to the application variable name. * The ng-bind directive binds the innerHTML of the <p> element to the application variable name. */ -<tag> Here are content to be intrepreted </tag> +<tag> Here are content to be interpreted </tag> /////////////////////////////////// // AngularJS Expressions @@ -275,7 +275,7 @@ angular.module('myApp', []).controller('namesCtrl', function($scope) { <script src="namesController.js"></script> /////////////////////////////////// -// AngularJS Filers +// AngularJS Filters // Filters can be added to expressions and directives using a pipe character. // AngularJS filters can be used to transform data: @@ -326,7 +326,7 @@ angular.module('myApp', []).controller('namesCtrl', function($scope) { //An input filter can be added to a directive with a pipe character (|) //and filter followed by a colon and a model name. -//The filter filter selects a subset of an array: +//The filter selects a subset of an array: <div ng-app="myApp" ng-controller="namesCtrl"> @@ -706,8 +706,3 @@ app.controller('myCtrl', function($scope) { - http://www.w3schools.com/angular/angular_ref_directives.asp - http://www.w3schools.com/angular/default.asp - https://teamtreehouse.com/library/angular-basics/ - -Feedback is welcome! You can find me in: -[@WalterC_87](https://twitter.com/WalterC_87), or -[me@waltercordero.com](mailto:me@waltercordero.com). - diff --git a/ar-ar/html-ar.html.markdown b/ar-ar/html-ar.html.markdown new file mode 100644 index 00000000..2f8ea019 --- /dev/null +++ b/ar-ar/html-ar.html.markdown @@ -0,0 +1,120 @@ +--- +language: html +filename: learnhtml-tf.html +contributors: + - ["Christophe THOMAS", "https://github.com/WinChris"] +translators: + - ["Ader", "https://github.com/y1n0"] +--- + +HTML اختصار ل HyperText Markup Language، أي "لغة ترميز النص التشعبي". +هي لغة تمكننا من كتابة صفحات موجهة لشبكة الويب العالمي. +هي لغة توصيف للنص، تسمح بكتابة صفحات ويب عن طريق تحديد كيفية عرض النصوص والمعلومات. +في الحقيقة، ملفات html هي ملفات تحتوي على نصوص بسيطة. +ما هو توصيف النص هذا؟ هو طريقة لتنظيم معلومات النص عن طريق إحاطته بوُسوم فتح ووسوم غلق. +هذه الوسوم تعطي معاني محددة للنص الذي تحيطه. +كباقي لغات الحاسوب، هناك الكثير من إصدارات HTML. سنتحدث هنا عن HTLM5. + +**ملاحظة:** يمكنك تجريب مختلف الوسوم والعناصر بينما تقرأ الدرس عبر موقع كـ [codepen](http://codepen.io/pen/) حتى ترى تأثيرها وتعرف كيف تعمل وتتعود على استعمالها. +هذه المادة تُعنى أساسا بتركيب HTML .وبعض النصائح المفيدة + + +```html +<!-- التعاليق تحاط بوسوم كما في هذا السطر --> + +<!-- #################### الوسوم #################### --> + +<!-- هنا مثال لملف html الذي سنقوم بالعمل عليه. --> + +<!doctype html> + <html> + <head> + <title>موقعي</title> + </head> + <body> + <h1>مرحبا بالعالم!</h1> + <a href = "http://codepen.io/anon/pen/xwjLbZ">الق نظرة كيف يبدو هذا من هنا</a> + <p>هذه فقرة.</p> + <p>هذه فقرة أخرى.</p> + <ul> + <li>هذا عنصر من لائحة غير مرقمة. (لائحة بالعرائض)</li> + <li>هذا عنصر آخر</li> + <li>وهذا آخر عنصر في اللائحة</li> + </ul> + </body> + </html> + +<!-- ملف HTML يُبتدأ دائما بتبيين أنه ملف HTML للمتصفح --> +<!doctype html> + +<!-- بعد هذا، يبدأ بفتح الوسم <html> --> +<html> + +<!-- الذي سيغلق في نهاية الملف بـ </html>. --> +</html> + +<!-- لا يجب كتابة أي شيء بعد وسم النهاية ذاك. --> + +<!-- داخل هذين الوسمين (<html></html>) نجد: --> + +<!-- "ترئيس" محدد ب <head> (يجب أن يغلق بـ </head>) --> +<!-- الترأيس يحتوي على أوصاف وبعض المعلومات الإضافية التي لا تظهر في المتصفح, تدعي metadata (المعلومات الوصفية) --> + +<head> + <title>موقعي</title><!-- الوسم <title> يحدد للمتصفح العنوان الذي يظهر في المكان المخصص للعنوان في نافذة المتصفح. --> +</head> + +<!-- بعد الجزء الخاص بـ <head>، نجد الوسم <body> --> +<!-- حتى هنا، لا شيء مما كُتب سيظهر في النافذة الرئيسية للمتصفح. --> +<!-- يجب ان نملأ "جسد" الصفحة بالمحتوى الذي نريد أن نُظهر --> + +<body> + <h1>مرحبا بالعالم!</h1> <!-- الوسم <h1> خاص بالعناوين الكبيرة. --> + <!-- هناك أيضا وسوم خاصة بالعناوين الفرعية من h1، الأكثر أهمية h2 والذي يليه حتى h6 الذي هو آخر عنوان داخلي. --> + <a href = "http://codepen.io/anon/pen/xwjLbZ">ألق نظرة كيف يبدو هذا من هنا</a> <!-- يظهر رابطا للصفحة التي داخل السمة href="" --> + <p>هذه فقرة.</p> <!-- يمكن من اضافة نصوص للصفحة. يميز الفقرات --> + <p>هذه فقرة أخرى.</p> + <ul> <!-- الوسم <ul> يخلق لائحة بالعرائض --> + <!-- إذا أردت لائحة مرقمة، هناك الوسم <ol>. ويكون الترتيب فيه حسب تموضع العناصر داخله، الأول فالأول. --> + <li>هذا عنصر من لائحة غير مرقمة. (لائحة بالعرائض)</li> + <li>هذا عنصر آخر</li> + <li>وهذا آخر عنصر في اللائحة</li> + </ul> +</body> + +<!-- وهكذا، كتابة ملفات HTML جد بسيطة --> + +<!-- يمكنك كذلك إضافة أنواع أخرى من الوسوم --> + +<!-- لادخال صورة: --> +<img src="http://i.imgur.com/XWG0O.gif"/> <!-- مصدر الصورة يحدد داخل السمة: src="" --> +<!-- مصدرها يمكن أن يكون رابطا أو مسارا لصورة في حاسوبك --> + +<!-- يمكنك كذلك تشكيل جداول. --> + +<table> <!-- نفتح الجدول بالوسم <table> --> + <tr> <!-- <tr> تسمح بتشكيل صف. --> + <th>العنوان الأول</th> <!-- <th> تسمح لنا بإعطاء عنوان لهذا العمود. --> + <th>العنوان الثاني</th> + </tr> + <tr> + <td>الصف الأول، العمود الأول</td> <!-- <td> تسمح بتشكيل الأعمدة، أو خانات داخل كل صف. --> + <td>الصف الأول، العمود الثاني</td> + </tr> + <tr> + <td>الصف الثاني، العمود الأول</td> + <td>الصف الثاني، العمود الأول</td> + </tr> +</table> + +``` + +## الاستعمال + +HTML يُكتب في ملفات تنتهي بـ `.html`. + +## لمعرفة المزيد + +* [wikipedia](https://en.wikipedia.org/wiki/HTML) +* [HTML tutorial](https://developer.mozilla.org/en-US/docs/Web/HTML) +* [W3School](http://www.w3schools.com/html/html_intro.asp) diff --git a/bf.html.markdown b/bf.html.markdown index c8bbee61..9c603303 100644 --- a/bf.html.markdown +++ b/bf.html.markdown @@ -10,7 +10,7 @@ minimal Turing-complete programming language with just 8 commands. You can try brainfuck on your browser with [brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/). -``` +```bf Any character not "><+-.,[]" (excluding quotation marks) is ignored. Brainfuck is represented by an array with 30,000 cells initialized to zero diff --git a/c++.html.markdown b/c++.html.markdown index 24d38df7..5220fb0b 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -456,7 +456,7 @@ void Dog::print() const Dog::~Dog() { - cout << "Goodbye " << name << "\n"; + std::cout << "Goodbye " << name << "\n"; } int main() { diff --git a/chapel.html.markdown b/chapel.html.markdown index 9c1daf40..4619785e 100644 --- a/chapel.html.markdown +++ b/chapel.html.markdown @@ -10,7 +10,7 @@ In short, Chapel is an open-source, high-productivity, parallel-programming lang More information and support can be found at the bottom of this document. -```c +```chapel // Comments are C-family style // one line comment /* diff --git a/coffeescript.html.markdown b/coffeescript.html.markdown index 89a29677..2aae6966 100644 --- a/coffeescript.html.markdown +++ b/coffeescript.html.markdown @@ -6,15 +6,17 @@ contributors: filename: coffeescript.coffee --- -CoffeeScript is a little language that compiles one-to-one into the equivalent JavaScript, and there is no interpretation at runtime. -As one of the successors to JavaScript, CoffeeScript tries its best to output readable, pretty-printed and smooth-running JavaScript code, which works well in every JavaScript runtime. +CoffeeScript is a little language that compiles one-to-one into the equivalent +JavaScript, and there is no interpretation at runtime. As one of the successors +to JavaScript, CoffeeScript tries its best to output readable, pretty-printed +and smooth-running JavaScript code, which works well in every JavaScript runtime. +It also attempts to try and make JavaScript more in line with the trends of many +modern languages. See also [the CoffeeScript website](http://coffeescript.org/), which has a complete tutorial on CoffeeScript. ```coffeescript -# CoffeeScript is a hipster language. -# It goes with the trends of many modern languages. -# So comments are like Ruby and Python, they use number symbols. +# Comments are similar to Ruby and Python, using the hash symbol `#` ### Block comments are like these, and they translate directly to '/ *'s and '* /'s diff --git a/coldfusion.html.markdown b/coldfusion.html.markdown index 482612fe..97259f56 100644 --- a/coldfusion.html.markdown +++ b/coldfusion.html.markdown @@ -13,7 +13,7 @@ ColdFusion is a scripting language for web development. _**C**old**F**usion **M**arkup **L**anguage_ ColdFusion started as a tag-based language. Almost all functionality is available using tags. -```html +```cfm <em>HTML tags have been provided for output readability</em> <!--- Comments start with "<!---" and end with "--->" ---> @@ -232,7 +232,8 @@ ColdFusion started as a tag-based language. Almost all functionality is availabl <h1>Components</h1> <em>Code for reference (Functions must return something to support IE)</em> - +``` +```cfs <cfcomponent> <cfset this.hello = "Hello" /> <cfset this.world = "world" /> diff --git a/crystal.html.markdown b/crystal.html.markdown new file mode 100644 index 00000000..1449ff81 --- /dev/null +++ b/crystal.html.markdown @@ -0,0 +1,553 @@ +--- +language: crystal +filename: learncrystal.cr +contributors: + - ["Vitalii Elenhaupt", "http://veelenga.com"] + - ["Arnaud Fernandés", "https://github.com/TechMagister/"] + +--- + +```crystal + +# This is a comment + +# Everything is an object +nil.class #=> Nil +100.class #=> Int32 +true.class #=> Bool + +# Falsey values are: nil, false and null pointers +!nil #=> true : Bool +!false #=> true : Bool +!0 #=> false : Bool + +# Integers + +1.class #=> Int32 + +# Four signed integer types +1_i8.class #=> Int8 +1_i16.class #=> Int16 +1_i32.class #=> Int32 +1_i64.class #=> Int64 + +# Four unsigned integer types +1_u8.class #=> UInt8 +1_u16.class #=> UInt16 +1_u32.class #=> UInt32 +1_u64.class #=> UInt64 + +2147483648.class #=> Int64 +9223372036854775808.class #=> UInt64 + +# Binary numbers +0b1101 #=> 13 : Int32 + +# Octal numbers +0o123 #=> 83 : Int32 + +# Hexadecimal numbers +0xFE012D #=> 16646445 : Int32 +0xfe012d #=> 16646445 : Int32 + +# Floats + +1.0.class #=> Float64 + +# There are two floating point types +1.0_f32.class #=> Float32 +1_f32.class #=> Float32 + +1e10.class #=> Float64 +1.5e10.class #=> Float64 +1.5e-7.class #=> Float64 + +# Chars + +'a'.class #=> Char + +# Octal codepoint +'\101' #=> 'A' : Char + +# Unicode codepoint +'\u0041' #=> 'A' : Char + +# Strings + +"s".class #=> String + +# Strings are immutable +s = "hello, " #=> "hello, " : String +s.object_id #=> 134667712 : UInt64 +s += "Crystal" #=> "hello, Crystal" : String +s.object_id #=> 142528472 : UInt64 + +# Supports interpolation +"sum = #{1 + 2}" #=> "sum = 3" : String + +# Multiline string +"This is + multiline string" + +# String with double quotes +%(hello "world") #=> "hello \"world\"" + +# Symbols +# Immutable, reusable constants represented internally as Int32 integer value. +# They're often used instead of strings to efficiently convey specific, +# meaningful values + +:symbol.class #=> Symbol + +sentence = :question? # :"question?" : Symbol + +sentence == :question? #=> true : Bool +sentence == :exclamation! #=> false : Bool +sentence == "question?" #=> false : Bool + +# Arrays + +[1, 2, 3].class #=> Array(Int32) +[1, "hello", 'x'].class #=> Array(Int32 | String | Char) + +# Empty arrays should specify a type +[] # Syntax error: for empty arrays use '[] of ElementType' +[] of Int32 #=> [] : Array(Int32) +Array(Int32).new #=> [] : Array(Int32) + +# Arrays can be indexed +array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5] : Array(Int32) +array[0] #=> 1 : Int32 +array[10] # raises IndexError +array[-6] # raises IndexError +array[10]? #=> nil : (Int32 | Nil) +array[-6]? #=> nil : (Int32 | Nil) + +# From the end +array[-1] #=> 5 + +# With a start index and size +array[2, 3] #=> [3, 4, 5] + +# Or with range +array[1..3] #=> [2, 3, 4] + +# Add to an array +array << 6 #=> [1, 2, 3, 4, 5, 6] + +# Remove from the end of the array +array.pop #=> 6 +array #=> [1, 2, 3, 4, 5] + +# Remove from the beginning of the array +array.shift #=> 1 +array #=> [2, 3, 4, 5] + +# Check if an item exists in an array +array.includes? 3 #=> true + +# Special syntax for an array of string and an array of symbols +%w(one two three) #=> ["one", "two", "three"] : Array(String) +%i(one two three) #=> [:one, :two, :three] : Array(Symbol) + +# There is a special array syntax with other types too, as long as +# they define a .new and a #<< method +set = Set{1, 2, 3} #=> [1, 2, 3] +set.class #=> Set(Int32) + +# The above is equivalent to +set = Set(typeof(1, 2, 3)).new +set << 1 +set << 2 +set << 3 + +# Hashes + +{1 => 2, 3 => 4}.class #=> Hash(Int32, Int32) +{1 => 2, 'a' => 3}.class #=> Hash(Int32 | Char, Int32) + +# Empty hashes should specify a type +{} # Syntax error +{} of Int32 => Int32 # {} +Hash(Int32, Int32).new # {} + +# Hashes can be quickly looked up by key +hash = {"color" => "green", "number" => 5} +hash["color"] #=> "green" +hash["no_such_key"] #=> Missing hash key: "no_such_key" (KeyError) +hash["no_such_key"]? #=> nil + +# Check existence of keys hash +hash.has_key? "color" #=> true + +# Special notation for symbol and string keys +{key1: 'a', key2: 'b'} # {:key1 => 'a', :key2 => 'b'} +{"key1": 'a', "key2": 'b'} # {"key1" => 'a', "key2" => 'b'} + +# Special hash literal syntax with other types too, as long as +# they define a .new and a #[]= methods +class MyType + def []=(key, value) + puts "do stuff" + end +end + +MyType{"foo" => "bar"} + +# The above is equivalent to +tmp = MyType.new +tmp["foo"] = "bar" +tmp + +# Ranges + +1..10 #=> Range(Int32, Int32) +Range.new(1, 10).class #=> Range(Int32, Int32) + +# Can be inclusive or exclusive +(3..5).to_a #=> [3, 4, 5] +(3...5).to_a #=> [3, 4] + +# Check whether range includes the given value or not +(1..8).includes? 2 #=> true + +# Tuples are a fixed-size, immutable, stack-allocated sequence of values of +# possibly different types. +{1, "hello", 'x'}.class #=> Tuple(Int32, String, Char) + +# Acces tuple's value by its index +tuple = {:key1, :key2} +tuple[1] #=> :key2 +tuple[2] #=> syntax error : Index out of bound + +# Can be expanded into multiple variables +a, b, c = {:a, 'b', "c"} +a #=> :a +b #=> 'b' +c #=> "c" + +# Procs represent a function pointer with an optional context (the closure data) +# It is typically created with a proc litteral +proc = ->(x : Int32) { x.to_s } +proc.class # Proc(Int32, String) +# Or using the new method +Proc(Int32, String).new { |x| x.to_s } + +# Invoke proc with call method +proc.call 10 #=> "10" + +# Control statements + +if true + "if statement" +elsif false + "else-if, optional" +else + "else, also optional" +end + +puts "if as a suffix" if true + +# If as an expression +a = if 2 > 1 + 3 + else + 4 + end + +a #=> 3 + +# Ternary if +a = 1 > 2 ? 3 : 4 #=> 4 + +# Case statement +cmd = "move" + +action = case cmd + when "create" + "Creating..." + when "copy" + "Copying..." + when "move" + "Moving..." + when "delete" + "Deleting..." +end + +action #=> "Moving..." + +# Loops +index = 0 +while index <= 3 + puts "Index: #{index}" + index += 1 +end +# Index: 0 +# Index: 1 +# Index: 2 +# Index: 3 + +index = 0 +until index > 3 + puts "Index: #{index}" + index += 1 +end +# Index: 0 +# Index: 1 +# Index: 2 +# Index: 3 + +# But the preferable way is to use each +(1..3).each do |index| + puts "Index: #{index}" +end +# Index: 0 +# Index: 1 +# Index: 2 +# Index: 3 + +# Variable's type depends on the type of the expression +# in control statements +if a < 3 + a = "hello" +else + a = true +end +typeof a #=> (Bool | String) + +if a && b + # here both a and b are guaranteed not to be Nil +end + +if a.is_a? String + a.class #=> String +end + +# Functions + +def double(x) + x * 2 +end + +# Functions (and all blocks) implicitly return the value of the last statement +double(2) #=> 4 + +# Parentheses are optional where the call is unambiguous +double 3 #=> 6 + +double double 3 #=> 12 + +def sum(x, y) + x + y +end + +# Method arguments are separated by a comma +sum 3, 4 #=> 7 + +sum sum(3, 4), 5 #=> 12 + +# yield +# All methods have an implicit, optional block parameter +# it can be called with the 'yield' keyword + +def surround + puts '{' + yield + puts '}' +end + +surround { puts "hello world" } + +# { +# hello world +# } + + +# You can pass a block to a function +# "&" marks a reference to a passed block +def guests(&block) + block.call "some_argument" +end + +# You can pass a list of arguments, which will be converted into an array +# That's what splat operator ("*") is for +def guests(*array) + array.each { |guest| puts guest } +end + +# If a method returns an array, you can use destructuring assignment +def foods + ["pancake", "sandwich", "quesadilla"] +end +breakfast, lunch, dinner = foods +breakfast #=> "pancake" +dinner #=> "quesadilla" + +# By convention, all methods that return booleans end with a question mark +5.even? # false +5.odd? # true + +# And if a method ends with an exclamation mark, it does something destructive +# like mutate the receiver. Some methods have a ! version to make a change, and +# a non-! version to just return a new changed version +company_name = "Dunder Mifflin" +company_name.gsub "Dunder", "Donald" #=> "Donald Mifflin" +company_name #=> "Dunder Mifflin" +company_name.gsub! "Dunder", "Donald" +company_name #=> "Donald Mifflin" + + +# Define a class with the class keyword +class Human + + # A class variable. It is shared by all instances of this class. + @@species = "H. sapiens" + + # type of name is String + @name : String + + # Basic initializer + # Assign the argument to the "name" instance variable for the instance + # If no age given, we will fall back to the default in the arguments list. + def initialize(@name, @age = 0) + end + + # Basic setter method + def name=(name) + @name = name + end + + # Basic getter method + def name + @name + end + + # The above functionality can be encapsulated using the attr_accessor method as follows + property :name + + # Getter/setter methods can also be created individually like this + getter :name + setter :name + + # A class method uses self to distinguish from instance methods. + # It can only be called on the class, not an instance. + def self.say(msg) + puts msg + end + + def species + @@species + end +end + + +# Instantiate a class +jim = Human.new("Jim Halpert") + +dwight = Human.new("Dwight K. Schrute") + +# Let's call a couple of methods +jim.species #=> "H. sapiens" +jim.name #=> "Jim Halpert" +jim.name = "Jim Halpert II" #=> "Jim Halpert II" +jim.name #=> "Jim Halpert II" +dwight.species #=> "H. sapiens" +dwight.name #=> "Dwight K. Schrute" + +# Call the class method +Human.say("Hi") #=> print Hi and returns nil + +# Variables that start with @ have instance scope +class TestClass + @var = "I'm an instance var" +end + +# Variables that start with @@ have class scope +class TestClass + @@var = "I'm a class var" +end +# Variables that start with a capital letter are constants +Var = "I'm a constant" +Var = "can't be updated" # Already initialized constant Var + +# Class is also an object in crystal. So class can have instance variables. +# Class variable is shared among the class and all of its descendants. + +# base class +class Human + @@foo = 0 + + def self.foo + @@foo + end + + def self.foo=(value) + @@foo = value + end +end + +# derived class +class Worker < Human +end + +Human.foo #=> 0 +Worker.foo #=> 0 + +Human.foo = 2 #=> 2 +Worker.foo #=> 0 + +Worker.foo = 3 #=> 3 +Human.foo #=> 2 +Worker.foo #=> 3 + +module ModuleExample + def foo + "foo" + end +end + +# Including modules binds their methods to the class instances +# Extending modules binds their methods to the class itself + +class Person + include ModuleExample +end + +class Book + extend ModuleExample +end + +Person.foo # => undefined method 'foo' for Person:Class +Person.new.foo # => 'foo' +Book.foo # => 'foo' +Book.new.foo # => undefined method 'foo' for Book + + +# Exception handling + +# Define new exception +class MyException < Exception +end + +# Define another exception +class MyAnotherException < Exception; end + +ex = begin + raise MyException.new +rescue ex1 : IndexError + "ex1" +rescue ex2 : MyException | MyAnotherException + "ex2" +rescue ex3 : Exception + "ex3" +rescue ex4 # catch any kind of exception + "ex4" +end + +ex #=> "ex2" + +``` + +## Additional resources + +- [Official Documentation](http://crystal-lang.org/) diff --git a/cs-cz/elm.html.markdown b/cs-cz/elm.html.markdown index babd46a2..f19f9e8b 100644 --- a/cs-cz/elm.html.markdown +++ b/cs-cz/elm.html.markdown @@ -54,19 +54,19 @@ not False -- True ["příliš", "žluťoučký", "kůň", "úpěl"] [1, 2, 3, 4, 5] -- Druhý příklad lze zapsat také pomocí dvou teček. -[1..5] +List.range 1 5 -- Spojovat seznamy lze stejně jako řetězce. -[1..5] ++ [6..10] == [1..10] -- True +List.range 1 5 ++ List.range 6 10 == List.range 1 10 -- True -- K přidání položky do seznamu použijte funkci "cons". -0 :: [1..5] -- [0, 1, 2, 3, 4, 5] +0 :: List.range 1 5 -- [0, 1, 2, 3, 4, 5] -- Funkce "head" pro získání první položky seznamu i funkce "tail" pro získání následujích položek -- vrací typ Maybe. Místo zjišťování, jestli nějaká položka není null, -- se s chybějcími hodnotami vypořádáme explicitně. -List.head [1..5] -- Just 1 -List.tail [1..5] -- Just [2, 3, 4, 5] +List.head (List.range 1 5) -- Just 1 +List.tail (List.range 1 5) -- Just [2, 3, 4, 5] List.head [] -- Nothing -- List.nazevFunkce odkazuje na funkci, která žije v modulu List. @@ -82,7 +82,7 @@ snd ("elm", 42) -- 42 -- Je to jediná hodnota svého typu, který se také nazývá "Unit". () --- Záznamy jsou podobné n-ticím, ale prvky jsou pojmenovány. Na pořadí nezáleží. +-- Záznamy jsou podobné n-ticím, ale prvky jsou pojmenovány. Na pořadí nezáleží. -- Povšimněte si, že hodnoty vlastností se přiřazují rovnítky, ne dvojtečkami. { x = 3, y = 7 } @@ -153,10 +153,10 @@ odpoved = 42 -- Předejte funkci jako parametr jiným funkcím. -List.map zdvoj [1..4] -- [2, 4, 6, 8] +List.map zdvoj (List.range 1 4) -- [2, 4, 6, 8] -- Nebo použijte anonymní funkci. -List.map (\a -> a * 2) [1..4] -- [2, 4, 6, 8] +List.map (\a -> a * 2) (List.range 1 4) -- [2, 4, 6, 8] -- V definici funkce lze zapsat vzor, může-li nastat pouze jeden případ. -- Tato funkce přijímá jednu dvojici místo dvou parametrů. @@ -182,7 +182,7 @@ fib n = else fib (n - 1) + fib (n - 2) -List.map fib [0..8] -- [1, 1, 2, 3, 5, 8, 13, 21, 34] +List.map fib (List.range 0 8) -- [1, 1, 2, 3, 5, 8, 13, 21, 34] -- Jiná rekurzivní funkce (v praxi použijte List.length). delkaSeznamu seznam = @@ -339,11 +339,11 @@ $ elm repl -- Balíčky jsou určeny uživatelským jménem na GitHubu a názvem repozitáře. -- Nainstalujte nový balíček a uložte jej v souboru elm-package.json. -$ elm package install evancz/elm-html +$ elm package install evancz/elm-lang/html -- Porovnejte změny mezi verzemi jednoho balíčku. -$ elm package diff evancz/elm-html 3.0.0 4.0.2 --- Správce balíčků v Elmu vyžaduje sémantické verzování, +$ elm package diff elm-lang/html 1.1.0 2.0.0 +-- Správce balíčků v Elmu vyžaduje sémantické verzování, -- takže minor verze nikdy nerozbije váš build. ``` diff --git a/d.html.markdown b/d.html.markdown index edb3bff5..c682cfb5 100644 --- a/d.html.markdown +++ b/d.html.markdown @@ -6,7 +6,7 @@ contributors: lang: en --- -```c +```d // You know what's coming... module hello; @@ -28,7 +28,7 @@ D is actively developed by a large group of super-smart people and is spearheade [Andrei Alexandrescu](https://en.wikipedia.org/wiki/Andrei_Alexandrescu). With all that out of the way, let's look at some examples! -```c +```d import std.stdio; void main() { @@ -73,7 +73,7 @@ We can define new types with `struct`, `class`, `union`, and `enum`. Structs and are passed to functions by value (i.e. copied) and classes are passed by reference. Furthermore, we can use templates to parameterize all of these on both types and values! -```c +```d // Here, 'T' is a type parameter. Think '<T>' from C++/C#/Java. struct LinkedList(T) { T data = null; @@ -136,7 +136,7 @@ is roughly a function that may act like an lvalue, so we can have the syntax of POD structures (`structure.x = 7`) with the semantics of getter and setter methods (`object.setX(7)`)! -```c +```d // Consider a class parameterized on types 'T' & 'U'. class MyClass(T, U) { T _data; @@ -209,7 +209,7 @@ functions, and immutable data. In addition, all of your favorite functional algorithms (map, filter, reduce and friends) can be found in the wonderful `std.algorithm` module! -```c +```d import std.algorithm : map, filter, reduce; import std.range : iota; // builds an end-exclusive range @@ -237,7 +237,7 @@ is of some type A on any expression of type A as a method. I like parallelism. Anyone else like parallelism? Sure you do. Let's do some! -```c +```d // Let's say we want to populate a large array with the square root of all // consecutive integers starting from 1 (up until the size of the array), and we // want to do this concurrently taking advantage of as many cores as we have diff --git a/dart.html.markdown b/dart.html.markdown index fc7b220e..5027dc3e 100644 --- a/dart.html.markdown +++ b/dart.html.markdown @@ -11,7 +11,7 @@ its JavaScript sibling. Like JavaScript, Dart aims for great browser integration Dart's most controversial feature must be its Optional Typing. -```javascript +```dart import "dart:collection"; import "dart:math" as DM; diff --git a/dynamic-programming.html.markdown b/dynamic-programming.html.markdown index 94be22e9..7df367e7 100644 --- a/dynamic-programming.html.markdown +++ b/dynamic-programming.html.markdown @@ -9,7 +9,7 @@ contributors: ## Introduction -Dynamic Programming is a powerful technique used for solving a particular class of problems as we will see.The idea is very simple, If you have solved a problem with the given input, then save the result for future reference, so as to avoid solving the same problem again. +Dynamic Programming is a powerful technique used for solving a particular class of problems as we will see. The idea is very simple, If you have solved a problem with the given input, then save the result for future reference, so as to avoid solving the same problem again. Always remember! "Those who can't remember the past are condemned to repeat it" diff --git a/elm.html.markdown b/elm.html.markdown index 96554e84..99c23980 100644 --- a/elm.html.markdown +++ b/elm.html.markdown @@ -51,18 +51,18 @@ not False -- True ["the", "quick", "brown", "fox"] [1, 2, 3, 4, 5] -- The second example can also be written with two dots. -[1..5] +List.range 1 5 -- Append lists just like strings. -[1..5] ++ [6..10] == [1..10] -- True +List.range 1 5 ++ List.range 6 10 == List.range 1 10 -- True -- To add one item, use "cons". -0 :: [1..5] -- [0, 1, 2, 3, 4, 5] +0 :: List.range 1 5 -- [0, 1, 2, 3, 4, 5] -- The head and tail of a list are returned as a Maybe. Instead of checking -- every value to see if it's null, you deal with missing values explicitly. -List.head [1..5] -- Just 1 -List.tail [1..5] -- Just [2, 3, 4, 5] +List.head (List.range 1 5) -- Just 1 +List.tail (List.range 1 5) -- Just [2, 3, 4, 5] List.head [] -- Nothing -- List.functionName means the function lives in the List module. @@ -150,10 +150,10 @@ answer = 42 -- Pass functions as arguments to other functions. -List.map double [1..4] -- [2, 4, 6, 8] +List.map double (List.range 1 4) -- [2, 4, 6, 8] -- Or write an anonymous function. -List.map (\a -> a * 2) [1..4] -- [2, 4, 6, 8] +List.map (\a -> a * 2) (List.range 1 4) -- [2, 4, 6, 8] -- You can pattern match in function definitions when there's only one case. -- This function takes one tuple rather than two arguments. @@ -180,7 +180,7 @@ fib n = else fib (n - 1) + fib (n - 2) -List.map fib [0..8] -- [1, 1, 2, 3, 5, 8, 13, 21, 34] +List.map fib (List.range 0 8) -- [1, 1, 2, 3, 5, 8, 13, 21, 34] -- Another recursive function (use List.length in real code). listLength aList = @@ -335,10 +335,10 @@ $ elm repl -- Packages are identified by GitHub username and repo name. -- Install a new package, and record it in elm-package.json. -$ elm package install evancz/elm-html +$ elm package install elm-lang/html -- See what changed between versions of a package. -$ elm package diff evancz/elm-html 3.0.0 4.0.2 +$ elm package diff elm-lang/html 1.1.0 2.0.0 -- Elm's package manager enforces semantic versioning, so minor version bumps -- will never break your build! ``` diff --git a/erlang.html.markdown b/erlang.html.markdown index a57f295f..a9d280d7 100644 --- a/erlang.html.markdown +++ b/erlang.html.markdown @@ -183,9 +183,10 @@ is_pet(A) -> false. % Warning: not all valid Erlang expressions can be used as guard expressions; % in particular, our `is_cat` and `is_dog` functions cannot be used within the % guard sequence in `is_pet`'s definition. For a description of the -% expressions allowed in guard sequences, refer to this -% [section](http://erlang.org/doc/reference_manual/expressions.html#id81912) -% of the Erlang reference manual. +% expressions allowed in guard sequences, refer to the specific section +% in the Erlang reference manual: +% http://erlang.org/doc/reference_manual/expressions.html#guards + % Records provide a method for associating a name with a particular element in a % tuple. diff --git a/es-es/c++-es.html.markdown b/es-es/c++-es.html.markdown index 07c8bc03..bd1ad07c 100644 --- a/es-es/c++-es.html.markdown +++ b/es-es/c++-es.html.markdown @@ -20,11 +20,11 @@ fue diseñado para - soportar programación orientada a objetos - soportar programación genérica -Aunque su sintaxis puede ser más difícil o compleja que los nuevos lenguajes, -es ampliamente utilizado, ya que compila instrucciones nativas que pueden ser -directamente ejecutadas por el procesador y ofrece un estricto control sobre -el hardware (como C), mientras ofrece características de alto nivel como -genericidad, excepciones, y clases. Esta combinación de velocidad y +Aunque su sintaxis puede ser más difícil o compleja que los nuevos lenguajes, +es ampliamente utilizado, ya que compila instrucciones nativas que pueden ser +directamente ejecutadas por el procesador y ofrece un estricto control sobre +el hardware (como C), mientras ofrece características de alto nivel como +genericidad, excepciones, y clases. Esta combinación de velocidad y funcionalidad hace de C ++ uno de los lenguajes de programación más utilizados. ```c++ @@ -32,22 +32,22 @@ funcionalidad hace de C ++ uno de los lenguajes de programación más utilizados // Comparación con C //////////////////// -// C ++ es _casi_ un superconjunto de C y comparte su sintaxis básica para las +// C ++ es _casi_ un superconjunto de C y comparte su sintaxis básica para las // declaraciones de variables, tipos primitivos y funciones. -// Al igual que en C, el punto de entrada de tu programa es una función llamada -// main con un retorno de tipo entero. +// Al igual que en C, el punto de entrada de tu programa es una función llamada +// main con un retorno de tipo entero. // Este valor sirve como código de salida del programa. // Mira http://en.wikipedia.org/wiki/Exit_status para mayor información. int main(int argc, char** argv) { - // Los argumentos de la línea de comandos se pasan por argc y argv de la + // Los argumentos de la línea de comandos se pasan por argc y argv de la // misma manera que en C. - // argc indica el número de argumentos, - // y argv es un arreglo de strings de estilo C (char*) + // argc indica el número de argumentos, + // y argv es un arreglo de strings de estilo C (char*) // representando los argumentos. // El primer argumento es el nombre con el que el programa es llamado. - // argc y argv pueden omitirse si no te preocupan los argumentos, + // argc y argv pueden omitirse si no te preocupan los argumentos, // dejando la definición de la función como int main () // Un estado de salida 0 indica éxito. @@ -72,7 +72,7 @@ void func(); // función que puede aceptar cualquier número de argumentos // Use nullptr en lugar de NULL en C++ int* ip = nullptr; -// Las cabeceras (headers) estándar de C están disponibles en C ++, +// Las cabeceras (headers) estándar de C están disponibles en C ++, // pero tienen el prefijo "c" y no tienen sufijo .h. #include <cstdio> @@ -109,7 +109,7 @@ int main() // Argumentos de función por defecto //////////////////////////////////// -// Puedes proporcionar argumentos por defecto para una función si no son +// Puedes proporcionar argumentos por defecto para una función si no son // proporcionados por quien la llama. void doSomethingWithInts(int a = 1, int b = 4) @@ -134,7 +134,7 @@ void invalidDeclaration(int a = 1, int b) // Error! // Espacios de nombre ///////////////////// -// Espacios de nombres proporcionan ámbitos separados para variable, función y +// Espacios de nombres proporcionan ámbitos separados para variable, función y // otras declaraciones. // Los espacios de nombres se pueden anidar. @@ -162,8 +162,8 @@ void foo() int main() { - // Incluye todos los símbolos del espacio de nombre Second en el ámbito - // actual. Tenga en cuenta que simplemente foo() no funciona, ya que ahora + // Incluye todos los símbolos del espacio de nombre Second en el ámbito + // actual. Tenga en cuenta que simplemente foo() no funciona, ya que ahora // es ambigua si estamos llamando a foo en espacio de nombres Second o en // el nivel superior. using namespace Second; @@ -254,7 +254,7 @@ const string& barRef = bar; // Crea una referencia constante a bar. // modificados. barRef += ". Hola!"; // Error, referencia constante no puede ser modificada. -// Sidetrack: Antes de hablar más sobre referencias, hay que introducir un +// Sidetrack: Antes de hablar más sobre referencias, hay que introducir un // concepto llamado objeto temporal. Supongamos que tenemos el siguiente código: string tempObjectFun() { ... } string retVal = tempObjectFun(); @@ -267,16 +267,16 @@ string retVal = tempObjectFun(); // El objeto devuelto se llama objeto temporal. Objetos temporales son // creados cada vez que una función devuelve un objeto, y es destruido en el // fin de la evaluación de la expresión que encierra (Bueno, esto es lo que la -// norma dice, pero los compiladores están autorizados a cambiar este -// comportamiento. Busca "return value optimization" para ver mas detalles). +// norma dice, pero los compiladores están autorizados a cambiar este +// comportamiento. Busca "return value optimization" para ver mas detalles). // Así que en este código: foo(bar(tempObjectFun())) // Suponiendo que foo y bar existen, el objeto retornado de tempObjectFun es // pasado al bar, y se destruye antes de llamar foo. -// Ahora, de vuelta a las referencias. La excepción a la regla "en el extremo -// de la expresión encerrada" es si un objeto temporal se une a una +// Ahora, de vuelta a las referencias. La excepción a la regla "en el extremo +// de la expresión encerrada" es si un objeto temporal se une a una // referencia constante, en cuyo caso su vida se extiende al ámbito actual: void constReferenceTempObjectFun() { @@ -287,7 +287,7 @@ void constReferenceTempObjectFun() { } // Otro tipo de referencia introducida en C ++ 11 es específicamente para -// objetos temporales. No se puede tener una variable de este tipo, pero tiene +// objetos temporales. No se puede tener una variable de este tipo, pero tiene // prioridad en resolución de sobrecarga: void someFun(string& s) { ... } // Referencia regular @@ -302,7 +302,7 @@ someFun(tempObjectFun()); // Llama la versión con referencia temporal basic_string(const basic_string& other); basic_string(basic_string&& other); -// La idea es que si estamos construyendo una nueva cadena de un objeto temporal +// La idea es que si estamos construyendo una nueva cadena de un objeto temporal // (que va a ser destruido pronto de todos modos), podemos tener un constructor // mas eficiente que "rescata" partes de esa cadena temporal. Usted verá este // Concepto denominado "movimiento semántico". @@ -341,13 +341,13 @@ public: // Funciones que no modifican el estado del objeto // Deben marcarse como const. // Esto le permite llamarlas si se envia una referencia constante al objeto. - // También tenga en cuenta que las funciones deben ser declaradas - // explícitamente como _virtual_ para que sea reemplazada en las clases + // También tenga en cuenta que las funciones deben ser declaradas + // explícitamente como _virtual_ para que sea reemplazada en las clases // derivadas. - // Las funciones no son virtuales por defecto por razones de rendimiento. + // Las funciones no son virtuales por defecto por razones de rendimiento. virtual void print() const; - // Las funciones también se pueden definir en el interior + // Las funciones también se pueden definir en el interior // del cuerpo de la clase. // Funciones definidas como tales están entre líneas automáticamente. void bark() const { std::cout << name << " barks!\n"; } @@ -358,7 +358,7 @@ public: // (mira abajo) // El destructor debe ser virtual si una clase es dervada desde el; // Si no es virtual, entonces la clase derivada destructor - // No será llamada si el objeto se destruye a través de una referencia de + // No será llamada si el objeto se destruye a través de una referencia de // la clase base o puntero. virtual ~Dog(); @@ -392,7 +392,7 @@ void Dog::print() const Dog::~Dog() { - cout << "Adiós " << name << "\n"; + std::cout << "Adiós " << name << "\n"; } int main() { @@ -410,7 +410,7 @@ class OwnedDog : public Dog { void setOwner(const std::string& dogsOwner); - // Reemplaza el comportamiento de la función de impresión + // Reemplaza el comportamiento de la función de impresión // de todos los OwnedDogs. Mira // http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping // Para una introducción más general si no está familiarizado con el @@ -442,7 +442,7 @@ void OwnedDog::print() const // Inicialización y sobrecarga de operadores //////////////////////////////////////////// -// En C ++ se puede sobrecargar el comportamiento +// En C ++ se puede sobrecargar el comportamiento // de los operadores como +, -, *, /, etc. // Esto se hace mediante la definición de una función que es llamada // cada vez que se utiliza el operador. @@ -505,14 +505,14 @@ int main () { // Plantillas (Templates) ///////////////////////// -// Las plantillas en C++ se utilizan sobre todo en la programación genérica, -// a pesar de que son mucho más poderoso que los constructores genéricos -// en otros lenguajes. Ellos también soportan especialización explícita y -// parcial y clases de tipo estilo funcional; de hecho, son un lenguaje +// Las plantillas en C++ se utilizan sobre todo en la programación genérica, +// a pesar de que son mucho más poderoso que los constructores genéricos +// en otros lenguajes. Ellos también soportan especialización explícita y +// parcial y clases de tipo estilo funcional; de hecho, son un lenguaje // funcional Turing-completo incrustado en C ++! -// Empezamos con el tipo de programación genérica que podría estar -// familiarizado. +// Empezamos con el tipo de programación genérica que podría estar +// familiarizado. // Para definir una clase o función que toma un parámetro de tipo: template<class T> class Box { @@ -521,9 +521,9 @@ public: void insert(const T&) { ... } }; -// Durante la compilación, el compilador realmente genera copias de cada -// plantilla con parámetros sustituidos, por lo que la definición completa -// de la clase debe estar presente en cada invocación. +// Durante la compilación, el compilador realmente genera copias de cada +// plantilla con parámetros sustituidos, por lo que la definición completa +// de la clase debe estar presente en cada invocación. // Es por esto que usted verá clases de plantilla definidas // Enteramente en archivos de cabecera. @@ -537,8 +537,8 @@ intBox.insert(123); Box<Box<int> > boxOfBox; boxOfBox.insert(intBox); -// Hasta C++11, había que colocar un espacio entre los dos '>'s, -// de lo contrario '>>' serían analizados como el operador de desplazamiento +// Hasta C++11, había que colocar un espacio entre los dos '>'s, +// de lo contrario '>>' serían analizados como el operador de desplazamiento // a la derecha. @@ -558,9 +558,9 @@ void barkThreeTimes(const T& input) input.bark(); } -// Observe que no se especifica nada acerca de los tipos de parámetros aquí. -// El compilador generará y comprobará cada invocación de la plantilla, -// por lo que la función anterior funciona con cualquier tipo "T" +// Observe que no se especifica nada acerca de los tipos de parámetros aquí. +// El compilador generará y comprobará cada invocación de la plantilla, +// por lo que la función anterior funciona con cualquier tipo "T" // que tenga un método 'bark' constante! @@ -574,12 +574,12 @@ void printMessage() { cout << "Aprende C++ en " << Y << " minutos!" << endl; } -// Y usted puede especializar explícitamente plantillas -// para código más eficiente. -// Por supuesto, la mayor parte del mundo real que utiliza una especialización +// Y usted puede especializar explícitamente plantillas +// para código más eficiente. +// Por supuesto, la mayor parte del mundo real que utiliza una especialización // no son tan triviales como esta. -// Tenga en cuenta que usted todavía tiene que declarar la función (o clase) -// como plantilla incluso si ha especificado de forma explícita todos +// Tenga en cuenta que usted todavía tiene que declarar la función (o clase) +// como plantilla incluso si ha especificado de forma explícita todos // los parámetros. template<> @@ -601,7 +601,7 @@ printMessage<10>(); // Prints "Aprende C++ rapido en solo 10 minutos!" #include <exception> #include <stdexcept> -//Todas las excepciones lanzadas dentro del bloque _try_ pueden ser +//Todas las excepciones lanzadas dentro del bloque _try_ pueden ser // capturados por los siguientes manejadores _catch_. try { // No asignar excepciones en el heap usando _new_. @@ -651,7 +651,7 @@ void doSomethingWithAFile(const char* filename) // (Excepciones son la mejor forma de manejar los fallos, // pero algunos programadores, especialmente los que tienen un fondo C, // estan en desacuerdo sobre la utilidad de las excepciones). -// Ahora tenemos que comprobar cada llamado por fallos y cerrar el manejador +// Ahora tenemos que comprobar cada llamado por fallos y cerrar el manejador // del archivo si se ha producido un problema. bool doSomethingWithAFile(const char* filename) { @@ -716,7 +716,7 @@ void doSomethingWithAFile(const char* filename) // Compare esto con el uso de la clase de flujo de archivos de C++ (fstream) // fstream utiliza su destructor para cerrar el archivo. -// Los destructores son llamados automáticamente +// Los destructores son llamados automáticamente // cuando un objeto queda fuera del ámbito. void doSomethingWithAFile(const std::string& filename) { @@ -734,7 +734,7 @@ void doSomethingWithAFile(const std::string& filename) // 1. No importa lo que pase, // El recurso (en este caso el manejador de archivo) será limpiado. // Una vez que escribes el destructor correctamente, -// Es _imposible_ olvidar cerrar el identificador y permitir +// Es _imposible_ olvidar cerrar el identificador y permitir // fugas del recurso. // 2. Tenga en cuenta que el código es mucho más limpio. // El destructor se encarga de cerrar el archivo detrás de cámaras @@ -743,13 +743,13 @@ void doSomethingWithAFile(const std::string& filename) // Una excepción puede ser lanzado en cualquier lugar de la función // y la limpieza ocurrirá. -// Todo el código idiomático C++ utiliza RAII ampliamente para todos los +// Todo el código idiomático C++ utiliza RAII ampliamente para todos los // recursos. // Otros ejemplos incluyen // - Memoria usando unique_ptr y shared_ptr // - Contenedores (Containers) - la biblioteca estándar linked list, // vector (es decir, array con auto-cambio de tamaño), hash maps, etc. -// Destruimos todos sus contenidos de forma automática +// Destruimos todos sus contenidos de forma automática // cuando quedan fuera del ámbito. // - Mutex utilizando lock_guard y unique_lock @@ -758,9 +758,9 @@ void doSomethingWithAFile(const std::string& filename) // Cosas divertidas ///////////////////// -// Aspectos de C ++ que pueden sorprender a los recién llegados +// Aspectos de C ++ que pueden sorprender a los recién llegados // (e incluso algunos veteranos). -// Esta sección es, por desgracia, salvajemente incompleta; +// Esta sección es, por desgracia, salvajemente incompleta; // C++ es uno de los lenguajes con los que mas facil te disparas en el pie. // Tu puedes sobreescribir métodos privados! @@ -788,13 +788,13 @@ pt2 = nullptr; // Establece pt2 como null. *pt = nullptr; // Esto todavía compila, a pesar de que '*pt' es un bool! // '=' != '=' != '='! -// Llama Foo::Foo(const Foo&) o alguna variante (mira movimientos semanticos) +// Llama Foo::Foo(const Foo&) o alguna variante (mira movimientos semanticos) // copia del constructor. Foo f2; Foo f1 = f2; // Llama Foo::Foo(const Foo&) o variante, pero solo copia el 'Foo' parte de -// 'fooSub'. Cualquier miembro extra de 'fooSub' se descarta. Este +// 'fooSub'. Cualquier miembro extra de 'fooSub' se descarta. Este // comportamiento horrible se llama "Corte de objetos." FooSub fooSub; Foo f1 = fooSub; @@ -809,13 +809,13 @@ class Foo { ... }; vector<Foo> v; for (int i = 0; i < 10; ++i) v.push_back(Foo()); -// La siguiente línea establece el tamaño de v en 0, +// La siguiente línea establece el tamaño de v en 0, // pero los destructores no son llamados y los recursos no se liberan! v.empty(); v.push_back(Foo()); // Nuevo valor se copia en el primer Foo que insertamos -// En verdad destruye todos los valores en v. +// En verdad destruye todos los valores en v. // Consulta la sección acerca de los objetos temporales para la // explicación de por qué esto funciona. v.swap(vector<Foo>()); diff --git a/es-es/elixir-es.html.markdown b/es-es/elixir-es.html.markdown new file mode 100644 index 00000000..885165a6 --- /dev/null +++ b/es-es/elixir-es.html.markdown @@ -0,0 +1,457 @@ +--- +language: elixir +contributors: + - ["Joao Marques", "http://github.com/mrshankly"] + - ["Dzianis Dashkevich", "https://github.com/dskecse"] + - ["Ryan Plant", "https://github.com/ryanplant-au"] +translator: + - ["Adrian Carrascal", "https://github.com/acarrascalgarcia"] +filename: learnelixir-es.ex +lang: es-es + +--- + +Elixir es un lenguaje funcional moderno construido sobre la máquina virtual de Erlang. +Es completamente compatibe con Erlang, sin embargo, ofrece una sintaxis más estandar +y otras características más. + +```elixir + +# Los comentarios de única línea +# comienzan con un símbolo numérico. + +# No hay comentarios multilinea, +# pero se pueden apilar varios comentarios. + +# Para usar el shell de elixir se usa el comando `iex`. +# Los módulos se compilan con el comando `elixirc`. + +# Ambos deberían estar en la ruta si elixir se instaló correctamente. + +## --------------------------- +## -- Tipos básicos +## --------------------------- + +# Hay números +3 # integer +0x1F # integer +3.0 # float + +# Átomos, que son literales, una constante con nombre. Comienzan con `:`. +:hello # atom + +# Tuples that are stored contiguously in memory. +# Tuplas que se almacenan contiguamente en memoria. +{1,2,3} # tuple + +# Se puede acceder a un elemento de una tupla con la función `elem`: +elem({1, 2, 3}, 0) #=> 1 + +# Listas que se implementan como listas enlazadas. +[1,2,3] # list + +# Se puede acceder al primer y último elemento de la lista como: +[head | tail] = [1,2,3] +head #=> 1 +tail #=> [2,3] + +# En elixir, solo como Erlang, el `=` denota la coincidencia de patrones y +# no una asignación. +# +# This is how the above example of accessing the head and tail of a list works. +# Así es como el ejemplo anterior de acceder al +# primer y último elemento de una lista trabaja. + +# Una coincidencia de patrón errará cuando los lados no coincidan, en este ejemplo +# las tuplas tienen diferentes tamaños. +# {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2} + +# También hay binarios +<<1,2,3>> # binary + +# Cadenas y listas de caracteres +"hello" # string +'hello' # char list + +# Cadenas de varias lineas +""" +I'm a multi-line +string. +""" +#=> "I'm a multi-line\nstring.\n" + +# Todas las cadenas se codifican en UTF-8: +"héllò" #=> "héllò" + +# Las cadenas son solo binarios realmente, y la lista de caracteres solo listas. +<<?a, ?b, ?c>> #=> "abc" +[?a, ?b, ?c] #=> 'abc' + +# `?a` en elixir devuelve el valor ASCII para el caracter `a` +?a #=> 97 + +# Para concatenar listas se usa `++`, para binarios `<>` +[1,2,3] ++ [4,5] #=> [1,2,3,4,5] +'hello ' ++ 'world' #=> 'hello world' + +<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>> +"hello " <> "world" #=> "hello world" + +# Los rangos se representan como `start..end` (Es inclusivo) +1..10 #=> 1..10 +lower..upper = 1..10 # Se puede usar la coincidencia de patrones en los rangos también +[lower, upper] #=> [1, 10] + +# Los mapas son pares de llave-valor +genders = %{"david" => "male", "gillian" => "female"} +genders["david"] #=> "male" + +# Los mapas con llaves de tipo átomo se pueden usar como esto +genders = %{david: "male", gillian: "female"} +genders.gillian #=> "female" + +## --------------------------- +## -- Opetadores +## --------------------------- + +# Aritméticos +1 + 1 #=> 2 +10 - 5 #=> 5 +5 * 2 #=> 10 +10 / 2 #=> 5.0 + +# En elixir el operador `/` siempre devuelve un número flotante + +# Para hacer la división de número entero se debe usar `div` +div(10, 2) #=> 5 + +# Para obtener el residuo de la división se debe usar `rem` +rem(10, 3) #=> 1 + +# También hay operadores lógicos: `or`, `and` y `not`. +# Estos operadores esperan un boolean como su primer argumento. +true and true #=> true +false or true #=> true +# 1 and true #=> ** (ArgumentError) argument error + +# Elixir también provee `||`, `&&` y `!` donde acepta argumentos de cualquier tipo. +# Todos los valores excepto `false` y `nil` se evaluarán como verdadero. +1 || true #=> 1 +false && 1 #=> false +nil && 20 #=> nil +!true #=> false + +# Para comparaciones se tiene: `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` y `>` +1 == 1 #=> true +1 != 1 #=> false +1 < 2 #=> true + +# `===` y `!==` son más estrictos cuando comparan números: +1 == 1.0 #=> true +1 === 1.0 #=> false + +# También se puede comparar dos tipos de datos diferentes: +1 < :hello #=> true + +# No se necesita memorizar el orden pero es importante tenerlo en cuenta: +# number < atom < reference < functions < port < pid < tuple < list < bit string + +## --------------------------- +## -- Control de flujo +## --------------------------- + +# Expresión `if` +if false do + "This will never be seen" +else + "This will" +end + +# También está la expresión `unless` +unless true do + "This will never be seen" +else + "This will" +end + +# Se acuerda de la coincidencia de patrones? +# Muchas estructuras de control de flujo en elixir confían en ella. + +# `case` permite comparar un valor con muchos patrones: +case {:one, :two} do + {:four, :five} -> + "This won't match" + {:one, x} -> + "This will match and bind `x` to `:two` in this clause" + _ -> + "This will match any value" +end + +# Es común vincular el valor a `_` si no se necesita. +# Por ejemplo, si unicamente el primer elemento de la lista es importante: +[head | _] = [1,2,3] +head #=> 1 + +# Para una mejor lectura se puede hace lo siguiente: +[head | _tail] = [:a, :b, :c] +head #=> :a + +# `cond` permite comprobar muchas condiciones al mismo tiempo. +# Usar `cond` en vez de muchas expresiones `if` anidadas. +cond do + 1 + 1 == 3 -> + "I will never be seen" + 2 * 5 == 12 -> + "Me neither" + 1 + 2 == 3 -> + "But I will" +end + +# Es común estabecer la última condición como `true`, donde siempre va a coincidir. +cond do + 1 + 1 == 3 -> + "I will never be seen" + 2 * 5 == 12 -> + "Me neither" + true -> + "But I will (this is essentially an else)" +end + +# `try/catch` se usa para atrapar valores que se lanzan, también soporta una +# clausula `after` que se invoca sin importar si un valor se atrapó o no. +try do + throw(:hello) +catch + message -> "Got #{message}." +after + IO.puts("I'm the after clause.") +end +#=> I'm the after clause +# "Got :hello" + +## --------------------------- +## -- Módulos y Funciones +## --------------------------- + +# Anonymous functions (notice the dot) +# Funciones anónimas (Ver el punto `.`) +square = fn(x) -> x * x end +square.(5) #=> 25 + +# También aceptan muchas cláusulas y guards. +# Los guards permiten afinar las coincidencias de patrones, +# se indican por la palabra reservada `when`: +f = fn + x, y when x > 0 -> x + y + x, y -> x * y +end + +f.(1, 3) #=> 4 +f.(-1, 3) #=> -3 + +# Elixir también provee muchas funciones incorporadas. +# Esas están disponibles en el ámbito actual. +is_number(10) #=> true +is_list("hello") #=> false +elem({1,2,3}, 0) #=> 1 + +# Se pueden agrupar varias funciones en un módulo. Dentro de un módulo +# se usa `def` para definir las funciones. +defmodule Math do + def sum(a, b) do + a + b + end + + def square(x) do + x * x + end +end + +Math.sum(1, 2) #=> 3 +Math.square(3) #=> 9 + +# Para compilar el módulo simple de Math se guarda como `math.ex` y se usa `elixirc` +# en la terminal: elixirc math.ex + +# Dentro de un módulo se puede definir funciones con `def` y funciones privadas con `defp`. +# Una función definida con `def` está disponible para ser invocada desde otros módulos, +# una función privada se puede solo invocar localmente. +defmodule PrivateMath do + def sum(a, b) do + do_sum(a, b) + end + + defp do_sum(a, b) do + a + b + end +end + +PrivateMath.sum(1, 2) #=> 3 +# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError) + +# La declaración de funciones también soportan guards y múltiples cláusulas: +defmodule Geometry do + def area({:rectangle, w, h}) do + w * h + end + + def area({:circle, r}) when is_number(r) do + 3.14 * r * r + end +end + +Geometry.area({:rectangle, 2, 3}) #=> 6 +Geometry.area({:circle, 3}) #=> 28.25999999999999801048 +# Geometry.area({:circle, "not_a_number"}) +#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1 + +# Debido a la inmutabilidad, la recursión es una gran parte de elixir +defmodule Recursion do + def sum_list([head | tail], acc) do + sum_list(tail, acc + head) + end + + def sum_list([], acc) do + acc + end +end + +Recursion.sum_list([1,2,3], 0) #=> 6 + +# Los módulos de Elixir soportan atributos, hay atributos incorporados y +# se pueden agregar otros personalizados. +defmodule MyMod do + @moduledoc """ + This is a built-in attribute on a example module. + """ + + @my_data 100 # This is a custom attribute. + IO.inspect(@my_data) #=> 100 +end + +# El operador pipe |> permite que se pase la salida de una expresión +# como el primer parámetro en una función. + +Range.new(1,10) +|> Enum.map(fn x -> x * x end) +|> Enum.filter(fn x -> rem(x, 2) == 0 end) +#=> [4, 16, 36, 64, 100] + +## --------------------------- +## -- Structs and Excepciones +## --------------------------- + +# Los Structs son extensiones de los mapas que traen valores por defecto, +# garantes en tiempo de compilación y polimorfismo en Elixir. +defmodule Person do + defstruct name: nil, age: 0, height: 0 +end + +joe_info = %Person{ name: "Joe", age: 30, height: 180 } +#=> %Person{age: 30, height: 180, name: "Joe"} + +# Acceder al valor de name +joe_info.name #=> "Joe" + +# Actualizar el valor de age +older_joe_info = %{ joe_info | age: 31 } +#=> %Person{age: 31, height: 180, name: "Joe"} + +# El bloque `try` con la palabra reservada `rescue` se usa para manejar excepciones +try do + raise "some error" +rescue + RuntimeError -> "rescued a runtime error" + _error -> "this will rescue any error" +end +#=> "rescued a runtime error" + +# Todas las excepciones tienen un mensaje +try do + raise "some error" +rescue + x in [RuntimeError] -> + x.message +end +#=> "some error" + +## --------------------------- +## -- Concurrencia +## --------------------------- + +# Elixir confía en el modelo actor para la concurrencia. Todo lo que se necesita para escribir +# programas concurrentes en elixir son tres primitivas: procesos de desove, +# envío de mensajes y recepción de mensajes. + +# Para empezar un nuevo proceso se usa la función `spawn`, +# donde toma una función como argumento. +f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245> +spawn(f) #=> #PID<0.40.0> + +# `spawn` devuelve un pid (identificador de proceso), se puede usar este pid para enviar +# mensajes para el proceso. Para hacer que un mensaje pase se usa el operador `send`. +# Para que todo esto se útil se necesita estar disponibles para recibir mensajes. Esto se +# alcanza con el mecanismo `receive`: + +# El bloque `receive do` se usa para escuchar los mensajes y procesarlos +# cuando se reciben. Un bloque `receive do` solo procesará +# un mensaje recibido. Para procesar múltiples mensajes, +# una función con un bloque `receive do` tiene que llamarse recursivamente +# para entrar en el bloque `receive do` otra vez. + +defmodule Geometry do + def area_loop do + receive do + {:rectangle, w, h} -> + IO.puts("Area = #{w * h}") + area_loop() + {:circle, r} -> + IO.puts("Area = #{3.14 * r * r}") + area_loop() + end + end +end + +# Compilar el módulo y crear un proceso que evalue `area_loop` en el shell +pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0> +# Como alternativa +pid = spawn(Geometry, :area_loop, []) + +# Enviar un mensaje al `pid` que coincidirá con un patrón en el que recibe una sentencia +send pid, {:rectangle, 2, 3} +#=> Area = 6 +# {:rectangle,2,3} + +send pid, {:circle, 2} +#=> Area = 12.56000000000000049738 +# {:circle,2} + +# El shell también es un proceso, se puede usar `self` para obtener el pid actual +self() #=> #PID<0.27.0> + +## --------------------------- +## -- Agentes +## --------------------------- + +# Un agente es un proceso que mantiene el seguimiento de algún valor cambiante + +# Un agente se crea con `Agent.start_link`, introducuendole una función +# El estado inicial del agente será lo que sea que la función devuelva +{ok, my_agent} = Agent.start_link(fn -> ["red, green"] end) + +# `Agent.get` toma un nombre de agente y un `fn` que se pasa como el estado actual +# Lo que sea que este `fn` devuelva es lo que se obtendrá de vuelta +Agent.get(my_agent, fn colors -> colors end) #=> ["red, "green"] + +# El estado del agente se actualiza de la misma manera +Agent.update(my_agent, fn colors -> ["blue" | colors] end) +``` + +## Referencias + +* [Getting started guide](http://elixir-lang.org/getting-started/introduction.html) from the [Elixir website](http://elixir-lang.org) +* [Elixir Documentation](http://elixir-lang.org/docs/master/) +* ["Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) by Dave Thomas +* [Elixir Cheat Sheet](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf) +* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) by Fred Hebert +* ["Programming Erlang: Software for a Concurrent World"](https://pragprog.com/book/jaerlang2/programming-erlang) by Joe Armstrong diff --git a/forth.html.markdown b/forth.html.markdown index 55d755b2..09f3beb0 100644 --- a/forth.html.markdown +++ b/forth.html.markdown @@ -12,7 +12,7 @@ such as Open Firmware. It's also used by NASA. Note: This article focuses predominantly on the Gforth implementation of Forth, but most of what is written here should work elsewhere. -``` +```forth \ This is a comment ( This is also a comment but it's only used when defining words ) diff --git a/fortran95.html.markdown b/fortran95.html.markdown index 5d1424bf..8479fef8 100644 --- a/fortran95.html.markdown +++ b/fortran95.html.markdown @@ -17,7 +17,7 @@ This overview will discuss the features of Fortran 95 since it is the most widely implemented of the more recent specifications and the later versions are largely similar (by comparison FORTRAN 77 is a very different language). -``` +```fortran ! This is a comment. diff --git a/fr-fr/crystal-fr.html.markdown b/fr-fr/crystal-fr.html.markdown new file mode 100644 index 00000000..2c4e3dad --- /dev/null +++ b/fr-fr/crystal-fr.html.markdown @@ -0,0 +1,555 @@ +--- +language: crystal +filename: learncrystal-fr.cr +contributors: + - ["Vitalii Elenhaupt", "http://veelenga.com"] + - ["Arnaud Fernandés", "https://github.com/TechMagister/"] +translators: + - ["Arnaud Fernandés", "http://github.com/TechMagister/"] +lang: fr-fr +--- + +```crystal + +# Ceci est un commentaire + +# Tout est objet +nil.class #=> Nil +100.class #=> Int32 +true.class #=> Bool + +# Les valeurs fausses sont : nil, false et les pointeurs null +!nil #=> true : Bool +!false #=> true : Bool +!0 #=> false : Bool + +# Entiers + +1.class #=> Int32 + +# Quatre types d'entiers signés +1_i8.class #=> Int8 +1_i16.class #=> Int16 +1_i32.class #=> Int32 +1_i64.class #=> Int64 + +# Quatre types d'entiers non signés +1_u8.class #=> UInt8 +1_u16.class #=> UInt16 +1_u32.class #=> UInt32 +1_u64.class #=> UInt64 + +2147483648.class #=> Int64 +9223372036854775808.class #=> UInt64 + +# Nombre en base binaire +0b1101 #=> 13 : Int32 + +# Nombre en base octale +0o123 #=> 83 : Int32 + +# Nombres hexadécimaux +0xFE012D #=> 16646445 : Int32 +0xfe012d #=> 16646445 : Int32 + +# Nombres à virgule + +1.0.class #=> Float64 + +# Il y a deux types de nombres à virgule +1.0_f32.class #=> Float32 +1_f32.class #=> Float32 + +1e10.class #=> Float64 +1.5e10.class #=> Float64 +1.5e-7.class #=> Float64 + +# Caractères + +'a'.class #=> Char + +# Notation octale des caractères +'\101' #=> 'A' : Char + +# Notation unicode +'\u0041' #=> 'A' : Char + +# Chaînes de caratères + +"s".class #=> String + +# Les chaînes de caractères sont immuables +s = "hello, " #=> "hello, " : String +s.object_id #=> 134667712 : UInt64 +s += "Crystal" #=> "hello, Crystal" : String +s.object_id #=> 142528472 : UInt64 + +# Interpolation +"sum = #{1 + 2}" #=> "sum = 3" : String + +# Chaînes multilignes +"Ceci est une chaine sur +plusieurs lignes" + +# Une autre notation pour les chaînes de caratères +# qui permet d'insérer des guillemets +%(hello "world") #=> "hello \"world\"" + +# Symboles +# Ils sont immuables et réutilisables, ils sont représentés en interne par +# un Int32. Ils sont souvent utilisés à la place des chaînes de caractères +# quand l'identité est plus importante que le contenu + +:symbol.class #=> Symbol + +sentence = :question? # :"question?" : Symbol + +sentence == :question? #=> true : Bool +sentence == :exclamation! #=> false : Bool +sentence == "question?" #=> false : Bool + +# Tableaux + +[1, 2, 3].class #=> Array(Int32) +[1, "hello", 'x'].class #=> Array(Int32 | String | Char) + +# Un type doit être spécifié pour les tableaux vides +[] # Syntax error: for empty arrays use '[] of ElementType' +[] of Int32 #=> [] : Array(Int32) +Array(Int32).new #=> [] : Array(Int32) + +# Les tableaux peuvent être indexés +array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5] : Array(Int32) +array[0] #=> 1 : Int32 +array[10] # lève l'exception IndexError +array[-6] # lève l'exception IndexError +array[10]? #=> nil : (Int32 | Nil) +array[-6]? #=> nil : (Int32 | Nil) + +# À partir de la fin +array[-1] #=> 5 + +# Avec un index de début et la taille +array[2, 3] #=> [3, 4, 5] + +# Ou avec un intervalle +array[1..3] #=> [2, 3, 4] + +# L'ajout à un tableau peut se faire avec l'opérateur << +array << 6 #=> [1, 2, 3, 4, 5, 6] + +# Enlève la dernière entrée +array.pop #=> 6 +array #=> [1, 2, 3, 4, 5] + +# Enlève la première entrée +array.shift #=> 1 +array #=> [2, 3, 4, 5] + +# Vérifie si un élément est présent dans le tableau +array.includes? 3 #=> true + +# Syntaxe spéciale pour un tableau de chaîne de caractères ou de symboles +%w(one two three) #=> ["one", "two", "three"] : Array(String) +%i(one two three) #=> [:one, :two, :three] : Array(Symbol) + +# Il y a une syntaxe spéciale pour les tableaux et autres types +# du moment qu'ils définissent une méthode .new et #<< +set = Set{1, 2, 3} #=> [1, 2, 3] +set.class #=> Set(Int32) + +# Ce qui est ci dessus est équivalent à : +set = Set(typeof(1, 2, 3)).new +set << 1 +set << 2 +set << 3 + +# Tableaux associatifs + +{1 => 2, 3 => 4}.class #=> Hash(Int32, Int32) +{1 => 2, 'a' => 3}.class #=> Hash(Int32 | Char, Int32) + +# Un type doit être spécifié pour les tableaux associatifs vides +{} # Syntax error +{} of Int32 => Int32 # {} +Hash(Int32, Int32).new # {} + +# L'accès se fait via une clé +hash = {"color" => "green", "number" => 5} +hash["color"] #=> "green" +hash["no_such_key"] #=> Missing hash key: "no_such_key" (KeyError) +hash["no_such_key"]? #=> nil + +# Vérifie l'existence d'une clé +hash.has_key? "color" #=> true + +# Notation spéciale pour les clés si ce sont des symboles +# ou chaînes de caractères +{key1: 'a', key2: 'b'} # {:key1 => 'a', :key2 => 'b'} +{"key1": 'a', "key2": 'b'} # {"key1" => 'a', "key2" => 'b'} + +# De même que pour les tableaux simples, une syntaxe spéciale +# existe du moment que le type définit une méthode .new et #[]= +class MyType + def []=(key, value) + puts "do stuff" + end +end + +MyType{"foo" => "bar"} + +# Ce qui est équivalent à : +tmp = MyType.new +tmp["foo"] = "bar" +tmp + +# Intervalle + +1..10 #=> Range(Int32, Int32) +Range.new(1, 10).class #=> Range(Int32, Int32) + +# Ils peuvent être inclusifs ou exclusifs +(3..5).to_a #=> [3, 4, 5] +(3...5).to_a #=> [3, 4] + +# Vérifie si un intervalle contient une valeur +(1..8).includes? 2 #=> true + +# les tuples sont fixés en taille, immuables et alloués sur la pile +{1, "hello", 'x'}.class #=> Tuple(Int32, String, Char) + +# L'accès peut se faire en utilisant un index +tuple = {:key1, :key2} +tuple[1] #=> :key2 +tuple[2] #=> syntax error : Index out of bound + +# Ils peuvent être scindés en plusieurs variables +a, b, c = {:a, 'b', "c"} +a #=> :a +b #=> 'b' +c #=> "c" + +# Les procédures ( Proc ) sont des pointeurs de fonction +# avec un contexte optionel. Ils sont généralement créés avec +# cette notation : +proc = ->(x : Int32) { x.to_s } +proc.class # Proc(Int32, String) +# Ou en utilisant la méthode new +Proc(Int32, String).new { |x| x.to_s } + +# On les invoque avec la méthode call +proc.call 10 #=> "10" + +# Contrôle de flux + +if true + "if statement" +elsif false + "else-if, optional" +else + "else, also optional" +end + +puts "if as a suffix" if true + +# Le si ( if ) peut être utilisé pour une déclaration +a = if 2 > 1 + 3 + else + 4 + end + +a #=> 3 + +# Opérateur ternaire +a = 1 > 2 ? 3 : 4 #=> 4 + +# Aiguillage à l'aide du mot clé "case" +cmd = "move" + +action = case cmd + when "create" + "Creating..." + when "copy" + "Copying..." + when "move" + "Moving..." + when "delete" + "Deleting..." +end + +action #=> "Moving..." + +# Boucle +index = 0 +while index <= 3 + puts "Index: #{index}" + index += 1 +end +# Index: 0 +# Index: 1 +# Index: 2 +# Index: 3 + +index = 0 +until index > 3 + puts "Index: #{index}" + index += 1 +end +# Index: 0 +# Index: 1 +# Index: 2 +# Index: 3 + +# Mais il est préférable d'utiliser #each +(1..3).each do |index| + puts "Index: #{index}" +end +# Index: 0 +# Index: 1 +# Index: 2 +# Index: 3 + +# Le type d'une variable dépend du type de l'expression +# dans la déclaration du if +if a < 3 + a = "hello" +else + a = true +end +typeof a #=> (Bool | String) + +if a && b + # ici a et b ne sont pas null +end + +if a.is_a? String + a.class #=> String +end + +# Fonctions + +def double(x) + x * 2 +end + +# Les fonctions et tous les blocs retournent la valeur de la dernière évaluation +double(2) #=> 4 + +# Les parenthèses sont optionnelle quand l'appel n'est pas ambigü +double 3 #=> 6 + +double double 3 #=> 12 + +def sum(x, y) + x + y +end + +# Les arguments sont séparés par une virgule +sum 3, 4 #=> 7 + +sum sum(3, 4), 5 #=> 12 + +# yield +# Toutes les méthodes on un paramètre optionel et implicite de type bloc +# il peut être appelé avec le mot clé 'yield' +def surround + puts '{' + yield + puts '}' +end + +surround { puts "hello world" } + +# { +# hello world +# } + +# Un bloc peut être passé à une fonction +# Le "&" marque une référence à un bloc +def guests(&block) + block.call "some_argument" +end + +# Une liste d'arguments peut être donnée, qui sera convertie en tableau +# Pour cela, utilisez l'opérateur "*" +def guests(*array) + array.each { |guest| puts guest } +end + +# Si une méthode retourne un tableau, il peut être scindé +def foods + ["pancake", "sandwich", "quesadilla"] +end +breakfast, lunch, dinner = foods +breakfast #=> "pancake" +dinner #=> "quesadilla" + +# Par convention, toutes les méthodes qui retournent un booléen +# finissent par un point d'interrogation +5.even? # false +5.odd? # true + +# Si une méthode finit avec un point d'exclamation, c'est qu'elle fait une +# opération destructrice. Quelques méthodes ont une version "!" pour faire +# des changements et une version non-"!" pour retourner une nouvelle version +company_name = "Dunder Mifflin" +company_name.gsub "Dunder", "Donald" #=> "Donald Mifflin" +company_name #=> "Dunder Mifflin" +company_name.gsub! "Dunder", "Donald" +company_name #=> "Donald Mifflin" + + +# Les classes se définissent avec le mot clé "class" +class Human + + # Une variable de classe, partagée par toutes les instances + @@species = "H. sapiens" + + # "name" est une chaine de caratère ( String ) + @name : String + + # Constructeur basique, assigne l'argument à la variable "name" + # si l'age n'est pas donné, sa valeur sera de 0 + def initialize(@name, @age = 0) + end + + # Mutateur + def name=(name) + @name = name + end + + # Accesseur + def name + @name + end + + # La macro "property" va générer les deux précédentes méthodes + property :name + + # Les accesseurs/mutateurs peuvent aussi être créés individuellement + getter :name + setter :name + + # Une méthode de classe utilise "self" pour se distinguer d'une + # méthode d'instance. Elle ne peut être appelée qu'à partir de la classe + def self.say(msg) + puts msg + end + + def species + @@species + end +end + + +# Instantie une classe +jim = Human.new("Jim Halpert") + +dwight = Human.new("Dwight K. Schrute") + +# Appelons quelques méthodes +jim.species #=> "H. sapiens" +jim.name #=> "Jim Halpert" +jim.name = "Jim Halpert II" #=> "Jim Halpert II" +jim.name #=> "Jim Halpert II" +dwight.species #=> "H. sapiens" +dwight.name #=> "Dwight K. Schrute" + +# Appel de la méthode de classe +Human.say("Hi") #=> Affiche "Hi" et retourne nil + +# Les variables qui commencent par @ ont une portée d'instance +class TestClass + @var = "Je suis une variable d'instance" +end + +# Les variables qui commencent par @@ ont une portée de classe +class TestClass + @@var = "Je suis une variable de classe" +end +# Les constantes commencent par une lettre majuscule +Var = "Je suis constante" +Var = "impossible" # Already initialized constant Var + +# La classe est aussi un objet +# Les variables de classe sont partagées avec les descendants + +# Classe de base +class Human + @@foo = 0 + + def self.foo + @@foo + end + + def self.foo=(value) + @@foo = value + end +end + +# Classe dérivée +class Worker < Human +end + +Human.foo #=> 0 +Worker.foo #=> 0 + +Human.foo = 2 #=> 2 +Worker.foo #=> 0 + +Worker.foo = 3 #=> 3 +Human.foo #=> 2 +Worker.foo #=> 3 + +module ModuleExample + def foo + "foo" + end +end + +# Inclure (include) des modules ajoute leurs méthodes aux instances +# Étendre (extend) ajoute les méthodes à la classe + +class Person + include ModuleExample +end + +class Book + extend ModuleExample +end + +Person.foo # => undefined method 'foo' for Person:Class +Person.new.foo # => 'foo' +Book.foo # => 'foo' +Book.new.foo # => undefined method 'foo' for Book + + +# Gestion des exceptions + +# Définit un type d'exeption +class MyException < Exception +end + +# Définit une autre exception +class MyAnotherException < Exception; end + +ex = begin + raise MyException.new +rescue ex1 : IndexError + "ex1" +rescue ex2 : MyException | MyAnotherException + "ex2" +rescue ex3 : Exception + "ex3" +rescue ex4 # attrape toutes les autres exceptions + "ex4" +end + +ex #=> "ex2" + +``` + +## Ressources additionnelles + +- [Documentation Officielle (EN)](http://crystal-lang.org/) diff --git a/fr-fr/javascript-fr.html.markdown b/fr-fr/javascript-fr.html.markdown index f1977dac..faa22863 100644 --- a/fr-fr/javascript-fr.html.markdown +++ b/fr-fr/javascript-fr.html.markdown @@ -190,7 +190,7 @@ someNinthVar; // = 9 // Il y a des raccourcis pour les opérations mathématiques: someVar += 5; // équivalent pour someVar = someVar + 5; -someVar *= 10; // de même, someVar = someVar * 100; +someVar *= 10; // de même, someVar = someVar * 10; someVar++; // = someVar += 1; someVar--; // = someVar -= 1; diff --git a/fr-fr/rust-fr.html.markdown b/fr-fr/rust-fr.html.markdown index 6ab559a3..5a384864 100644 --- a/fr-fr/rust-fr.html.markdown +++ b/fr-fr/rust-fr.html.markdown @@ -19,11 +19,11 @@ Le 15 mai 2015, Rust 1.0 a été libéré avec une garantie complète de compati Bien que Rust soit un langage relativement bas niveau, Rust a quelques concepts fonctionnels qui se trouvent généralement dans les langues de niveau supérieur. Cela rend Rust non seulement rapide, mais aussi efficace et facile à coder. ```rust -// Ceci est un commentaire. commentaires de ligne ressemblent à ceci ... -// Et prolonger plusieurs lignes comme celle-ci. +// Ceci est un commentaire. Les commentaires de ligne ressemblent à ceci... +// et continuent sur plusieurs lignes comme cela. -/// Les commentaires de documentation ressemblent à ceci et à soutenir -/// la notation de démarques. +/// Les commentaires de documentation ressemblent à ça et supportent la +/// syntaxe Markdown. /// # Exemples /// /// ``` @@ -37,7 +37,7 @@ Bien que Rust soit un langage relativement bas niveau, Rust a quelques concepts // Les fonctions // `I32` est le type 32 bits entiers signés fn add2(x: i32, y: i32) -> i32 { - // Retour implicite (pas virgule) + // Retour implicite (pas de point virgule) x + y } @@ -45,19 +45,19 @@ fn add2(x: i32, y: i32) -> i32 { fn main() { // Nombres // - // Reliures immutable + // Liaison immutable let x: i32 = 1; - // Entier suffixes/float + // Suffixes entiers et flottants let y: I32 = 13i32; let f: f64 = 1.3f64; - // Type Inférence - // La plupart du temps, le compilateur Rust peut déduire le type de variable - // est, donc vous ne devez pas écrire une annotation de type explicite. + // Inférence de type + // La plupart du temps, le compilateur Rust peut déduire quel est le type + // de variable, donc vous n'avez pas à écrire une annotation de type explicite. // Tout au long de ce tutoriel, les types sont explicitement annotées dans // de nombreux endroits, mais seulement à des fins de démonstration. - // L'inférence de type peut gérer cela pour vous la plupart du temps. + // L'inférence de type peut les générer pour vous la plupart du temps. let implicit_x = 1; let implicit_f = 1,3; @@ -71,22 +71,22 @@ fn main() { // Chaînes // - // Littéraux chaîne - let x: &str = "Bonjour tout le monde!"; + // Chaîne littérales + let x: &str = "Bonjour tout le monde !"; - // Impression + // Affichage println!("{} {}", f, x); // 1.3 Bonjour tout le monde - // A `Chaîne` - une chaîne de tas alloué + // Une `Chaîne` - une chaîne de tas alloué let s: String = "Bonjour tout le monde".to_string(); - // Une tranche de chaîne - une vue immutable dans une else chaîne. - // Ceci est essentiellement un pointeur immutable à une chaîne - il n'a pas - // contient effectivement le contenu d'une chaîne, juste un pointeur vers - // quelque chose qui fait(dans ce cas, `s`). + // Un morceau de chaîne - une vue immutable sur une autre chaîne. + // C'est essentiellement un pointeur immutable sur une chaîne - ça ne + // contient effectivement pas le contenu d'une chaîne, juste un pointeur vers + // le début et la fin de la chaîne. let s_slice: &str = &s; - println!("{} {}", s, s_slice); // Bonjour monde Bonjour tout le monde + println!("{} {}", s, s_slice); // Bonjour tout le monde Bonjour tout le monde // Vecteurs/tableau // @@ -97,20 +97,19 @@ fn main() { let mut vecteur: Vec<i32> = vec![1, 2, 3, 4]; vecteur.push(5); - // Une tranche - une vue immutable dans un vecteur ou un tableau. - // Ceci est un peu comme une tranche de chaîne, mais pour les vecteurs. + // Une tranche - une vue immutable sur un vecteur ou un tableau. + // Ceci est un peu comme un morceau de chaîne, mais pour les vecteurs. let tranche: &[i32] = &vecteur; - // Utiliser `{:?}` pour imprimer quelque chose de débogage de style + // Utiliser `{:?}` pour afficher quelque chose en mode debug println!("{:?} {:?}", vecteur, tranche); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] // Tuples // - // Un tuple est un ensemble de valeurs de peut-être différents types. - // de taille fixe + // Un tuple est un ensemble de valeurs qui peuvent être de différents types. let x:(i32, &str, f64) = (1, "bonjour", 3.4); - // Déstructurante `let` + // Déstructurer `let` let (a, b, c) = x; println!("{} {} {}", a, b, c); // 1 bonjour 3.4 diff --git a/fsharp.html.markdown b/fsharp.html.markdown index 69f4eb60..bbf477ba 100644 --- a/fsharp.html.markdown +++ b/fsharp.html.markdown @@ -408,11 +408,14 @@ module ActivePatternExamples = // "banana clips" are the syntax for active patterns + // You can use "elif" instead of "else if" in conditional expressions. + // They are equivalent in F# + // for example, define an "active" pattern to match character types... let (|Digit|Letter|Whitespace|Other|) ch = if System.Char.IsDigit(ch) then Digit - else if System.Char.IsLetter(ch) then Letter - else if System.Char.IsWhiteSpace(ch) then Whitespace + elif System.Char.IsLetter(ch) then Letter + elif System.Char.IsWhiteSpace(ch) then Whitespace else Other // ... and then use it to make parsing logic much clearer diff --git a/html.html.markdown b/html.html.markdown index b64cec33..3c855b5c 100644 --- a/html.html.markdown +++ b/html.html.markdown @@ -9,7 +9,7 @@ translators: HTML stands for HyperText Markup Language. It is a language which allows us to write pages for the world wide web. -It is a markup language, it enables us to write to write webpages using code to indicate how text and data should be displayed. +It is a markup language, it enables us to write webpages using code to indicate how text and data should be displayed. In fact, html files are simple text files. What is this markup? It is a method of organising the page's data by surrounding it with opening tags and closing tags. This markup serves to give significance to the text that it encloses. diff --git a/it-it/c++-it.html.markdown b/it-it/c++-it.html.markdown index 4af30176..b4f9c50e 100644 --- a/it-it/c++-it.html.markdown +++ b/it-it/c++-it.html.markdown @@ -461,7 +461,7 @@ void Cane::print() const Cane::~Cane() { - cout << "Ciao ciao " << nome << "\n"; + std::cout << "Ciao ciao " << nome << "\n"; } int main() { @@ -647,7 +647,7 @@ void stampaMessaggio<10>() { printMessage<20>(); // Stampa "impara il C++ in 20 minuti!" printMessage<10>(); // Stampa "Impara il C++ più velocemente in soli 10 minuti!" - + //////////////////////////// // Gestione delle eccezioni /////////////////////////// @@ -658,7 +658,7 @@ printMessage<10>(); // Stampa "Impara il C++ più velocemente in soli 10 minuti #include <exception> #include <stdexcept> -// Tutte le eccezioni lanciate all'interno del blocco _try_ possono essere catturate dai successivi +// Tutte le eccezioni lanciate all'interno del blocco _try_ possono essere catturate dai successivi // handlers _catch_. try { // Non allocare eccezioni nello heap usando _new_. diff --git a/ja-jp/python3-jp.html.markdown b/ja-jp/python3-jp.html.markdown new file mode 100644 index 00000000..3b1a0d73 --- /dev/null +++ b/ja-jp/python3-jp.html.markdown @@ -0,0 +1,898 @@ +--- +language: python3 +contributors: + - ["Louie Dinh", "http://pythonpracticeprojects.com"] + - ["Steven Basart", "http://github.com/xksteven"] + - ["Andre Polykanine", "https://github.com/Oire"] + - ["Zachary Ferguson", "http://github.com/zfergus2"] + - ["evuez", "http://github.com/evuez"] +translators: + - ["kakakaya", "https://github.com/kakakaya"] +filename: learnpython3-jp.py +lang: ja-jp +--- + +90年代の初め、Guido Van RossumによってPythonは作成されました。現在となっては、最も有名な言語の1つです。 +私は構文の明快さによって、Pythonと恋に落ちました。 +以下は基本的に実行可能な疑似コードです。 + +フィードバッグは大歓迎です! [@louiedinh](http://twitter.com/louiedinh) または louiedinh [at] [google's email service] にご連絡下さい! + +Note: この記事はPython 3に内容を絞っています。もし古いPython 2.7を学習したいなら、 [こちら](http://learnxinyminutes.com/docs/python/) をご確認下さい。 + +```python + +# 1行のコメントは番号記号(#)から始まります。 + +""" 複数行の文字は、"を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 + +# 除算の結果は常に浮動小数点になります。 +10.0 / 3 # => 3.3333333333333335 + +# 剰余の計算 +7 % 3 # => 1 + +# 冪乗 (x**y, x の y 乗) +2**4 # => 16 + +# 括弧により、計算の順番を優先させられます。 +(1 + 3) * 2 # => 8 + +# 真偽値はプリミティブ型です(大文字から始まっていることに注意!) +True +False + +# not で真偽を反転させられます。 +not True # => False +not False # => True + +# ブール演算 +# 注意: "and" と "or" は小文字です +True and False # => False +False or True # => True + +# 整数でブール演算をするときのメモ +0 and 2 # => 0 +-5 or 0 # => -5 +0 == False # => True +2 == True # => False +1 == True # => 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 + +# (is vs. ==) +# "is" は、2つの変数が同一のオブジェクトを参照しているか確認します。 +# 一方 "==" は、それぞれが参照する2つのオブジェクトが同じ値を持つか確認します。 +a = [1, 2, 3, 4] # a は新しいリストの [1, 2, 3, 4] を指します。 +b = a # b は a が指すリストを指します。 +b is a # => True, a と b は同一のオブジェクトを参照しています。 +b == a # => True, a と b が参照するオブジェクトの値は等しいです。 +b = [1, 2, 3, 4] # b は新しいリストの [1, 2, 3, 4] を指します。 +b is a # => False, a と b は別々のオブジェクトを参照しています。 +b == a # => True, a と b が参照するオブジェクトの値は等しいです。 + +# " または ' を使って文字列を作成します。 +"This is a string." +'This is also a string.' + +# 文字列も加算をすることができます!でも、あまり行わないように。 +"Hello " + "world!" # => "Hello world!" +# '+' を使わなくても連結はできます。 +"Hello " "world!" # => "Hello world!" + +# 文字列は文字のリストであるかのように扱うことができます。 +"This is a string"[0] # => 'T' + +# 文字列の長さを得るにはこのようにします。 +len("This is a string") # => 16 + +# .format で文字列のフォーマットを行えます +"{} can be {}".format("Strings", "interpolated") # => "Strings can be interpolated" + +# 入力を減らすために、フォーマットするときに引数を繰り返し使うことができます。 +"{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick") +# => "Jack be nimble, Jack be quick, Jack jump over the candle stick" + +# 引数の順番を数えるのがお嫌い?キーワード引数をどうぞ。 +"{name} wants to eat {food}".format(name="Bob", food="lasagna") # => "Bob wants to eat lasagna" + +# もし Python 3 のコードを Python 2.5以下でも使う必要があるなら、 +# 旧式のフォーマット方法を使うこともできます。 +"%s can be %s the %s way" % ("Strings", "interpolated", "old") # => "Strings can be interpolated the old way" + + +# None はオブジェクトです(大文字からです!) +None # => None + +# オブジェクトがNoneであるか確認するのに "==" 演算子を使わないように。 +# 代わりに "is" を使いましょう。オブジェクトの素性を確認できます。 +"etc" is None # => False +None is None # => True + +# None や 0 、空の 文字列/リスト/辞書/タプル は全て False として評価されます。 +# 他の全ての値は True になります。 +bool(0) # => False +bool("") # => False +bool([]) # => False +bool({}) # => False +bool(()) # => False + +#################################################### +# 2. Variables and Collections +#################################################### + +# Python にはprint関数があります。 +print("I'm Python. Nice to meet you!") # => I'm Python. Nice to meet you! + +# 標準では、print関数は最後に改行を出力します。 +# この動作を変更するためには、オプション引数を利用します。 +print("Hello, World", end="!") # => Hello, World! + +# コンソールから入力を得るための簡単な例 +input_string_var = input("Enter some data: ") # 入力を文字列として返します +# Note: Python の初期のバージョンでは、 input() は raw_input() という名前で存在します。 + +# 変数に代入する前に宣言する必要はありません。 +# 慣例的に、小文字でアンダースコア区切り ( lower_case_with_underscores ) の変数が使われます。 +some_var = 5 +some_var # => 5 + +# 代入されていない変数へのアクセスは例外を引き起こします。 +# 例外の取り扱いについては、3章の制御の流れをご確認ください。 +some_unknown_var # NameError を送出します + +# ifは式として使用できます。 +# C言語の「?:(三項演算子)」に対応する例: +"yahoo!" if 3 > 2 else 2 # => "yahoo!" + +# リストは順序を保存します。 +li = [] +# 値の入っているリストも作成できます。 +other_li = [4, 5, 6] + +# append により、リストの末尾にものを入れられます。 +li.append(1) # li is now [1] +li.append(2) # li is now [1, 2] +li.append(4) # li is now [1, 2, 4] +li.append(3) # li is now [1, 2, 4, 3] +# pop でリストの末尾から取り除けます。 +li.pop() # => 3 and li is now [1, 2, 4] +# 元に戻しましょう! +li.append(3) # li is now [1, 2, 4, 3] again. + +# 配列のように、リストにアクセスできます。 +li[0] # => 1 +# 最後の要素を参照できます。 +li[-1] # => 3 + +# 範囲外の要素を参照すると IndexError になります。 +li[4] # IndexError が発生します + +# スライス構文により範囲を参照できます。 +li[1:3] # => [2, 4] +# 先端を取り除く +li[2:] # => [4, 3] +# 末尾を取り除く +li[:3] # => [1, 2, 4] +# 1つ飛ばしで選択する +li[::2] # =>[1, 4] +# 反転したリストを得る +li[::-1] # => [3, 4, 2, 1] +# これらの任意の組み合わせにより、より複雑なスライスを作ることができます。 +# li[start:end:step] + +# スライスにより、深いコピーを1階層分行うことができます。 +li2 = li[:] # => li2 = [1, 2, 4, 3] だが、 (li2 is li) はFalseになる。 + +# "del"によりリストから任意の要素を削除できます。 +del li[2] # li は [1, 2, 3] になりました。 + +# "remove"で最初に出現する要素を削除できます。 +li.remove(2) # li は [1, 3] になりました。 +li.remove(2) # 2はリストの中に存在しないので、 ValueError が発生します。 + +# 要素を好きなところに挿入できます。 +li.insert(1, 2) # li は [1, 2, 3] に戻りました。 + +# "index"で引数の要素が最初に出現する場所のインデックスを得られます。 +li.index(2) # => 1 +li.index(4) # 4はリストの中に存在しないので、 ValueError が発生します。 + +# リスト同士を足すこともできます。 +# Note: li と other_li の値は変更されません。 +li + other_li # => [1, 2, 3, 4, 5, 6] + +# "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 が発生します。 + +# 長さが1のタプルを作成するには、要素の後にカンマを付ける必要があります。 +# しかし、それ以外の長さなら、例え長さが0でもそのようにする必要はありません。 +type((1)) # => <class 'int'> +type((1,)) # => <class 'tuple'> +type(()) # => <class 'tuple'> + +# 大抵のリスト操作はタプルでも行うことができます。 +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, b, c にはそれぞれ 1, 2, 3 が代入されました。 +# 拡張記法もあります。 +a, *b, c = (1, 2, 3, 4) # a は 1 、 b は [2, 3] 、c は4 になります。 +# 括弧を作成しなくてもデフォルトでタプルが作成されます。 +d, e, f = 4, 5, 6 +# 2つの変数を交換するのがどれほど簡単か見てみましょう。 +e, d = d, e # d は 5 、 e は e になります。 + + +# 辞書はマップ(キーと値の組み合わせ)を保存できます。 +empty_dict = {} +# 値が入っている辞書を直接作成することもできます。 +filled_dict = {"one": 1, "two": 2, "three": 3} + +# キーは不変の型である必要があります。 +# これは、高速化のため、キーを定数のハッシュ値に変換できるようにするためです。 +# 不変の型の例として、int、float、string、tupleなどが上げられます。 +invalid_dict = {[1, 2, 3]: "123"} # => list はハッシュ化できないので、 TypeError が発生します。 +valid_dict = {(1, 2, 3): [1, 2, 3]} # 一方、キーに対応する値はどのような型でも利用できます。 + +# [] で 値を取り出せます。 +filled_dict["one"] # => 1 + +# "keys()"により、全てのキーを反復可能な形式で取り出せます。 +# これをリストにするために、"list()"で囲んでいます。これについては後程解説します。 +# Note: 辞書のキーの順番は考慮されていません。実行した結果がこれと異なる場合があります。 +list(filled_dict.keys()) # => ["three", "two", "one"] + +# "values()"により、全ての値を反復可能な形式で取り出せます。 +# 前と同じように、これをリストにするために、"list()"で囲んでいます。 +# Note: 辞書の値の順番は考慮されていません。実行した結果がこれと異なる場合があります。 +list(filled_dict.values()) # => [3, 2, 1] + + +# "in" により、辞書のキーが存在するか確認できます。 +"one" in filled_dict # => True +1 in filled_dict # => False + +# 存在しないキーで辞書を参照すると KeyError になります。 +filled_dict["four"] # KeyError + +# "get()" メソッドを使うことで KeyError を回避できます。 +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 のままです。 + +# 辞書にマップを追加する +filled_dict.update({"four": 4}) # => {"one": 1, "two": 2, "three": 3, "four": 4} +# filled_dict["four"] = 4 # 辞書に追加する別の方法 + +# del により辞書からキーを削除できます。 +del filled_dict["one"] # "one" キーを辞書から削除します。 + +# Python 3.5 以降では、追加の値を取り出す方法があります。 +{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2} +{'a': 1, **{'a': 2}} # => {'a': 2} + + +# set では集合を表現できます。 +empty_set = set() +# 集合を一連の値で初期化する例です。辞書に似ていますね?ごめんなさい。 +some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4} + +# 辞書のキーのように、集合の値は不変である必要があります。 +invalid_set = {[1], 1} # => list はハッシュ化できないので、 TypeError が送出されます。 +valid_set = {(1,), 1} + +# 新しい値を集合にセットできます。 +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} + +# ^ により、集合同士の対象差が得られます。 +{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5} + +# 左の集合が右の集合の上位集合であるか確認。 +{1, 2} >= {1, 2, 3} # => False + +# 左の集合が右の集合の部分集合であるか確認。 +{1, 2} <= {1, 2, 3} # => True + +# in により値が集合の中に存在するか確認できます。 +2 in filled_set # => True +10 in filled_set # => False + + +#################################################### +# 3. 制御の流れとiterable +#################################################### + +# まずは変数を作りましょう。 +some_var = 5 + +# これはif文です。インデントがPythonでは特徴的ですね! +# 以下の例では"some_var is smaller than 10"と出力されます。 +if some_var > 10: + print("some_var is totally bigger than 10.") +elif some_var < 10: # この elif 節はオプションです。 + print("some_var is smaller than 10.") +else: # この else 節もオプションです。 + print("some_var is indeed 10.") + + +""" +for ループはリストの要素を反復することができます。 +出力: + dog is a mammal + cat is a mammal + mouse is a mammal +""" +for animal in ["dog", "cat", "mouse"]: + # format() を使って文字列に変数を挿入して出力できます。 + print("{} is a mammal".format(animal)) + +""" +"range(数値)" は、ゼロから与えられた数値までのiterableを返します。 +出力: + 0 + 1 + 2 + 3 +""" +for i in range(4): + print(i) + +""" +"range(lower, upper)" は、 lower の数値から upper の数値までのiterableを返します。 +upper の数値は含まれません。 +出力: + 4 + 5 + 6 + 7 +""" +for i in range(4, 8): + print(i) + +""" +"range(lower, upper, step)" は、lower の数値から upper の数値までが、 +step 刻みで表現されるiterableを返します +step が与えられない場合、デフォルトは1になります。 +出力: + 4 + 6 +""" +for i in range(4, 8, 2): + 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("This is an index error") +except IndexError as e: + pass # pass は、何もしないという命令(no-op)に相当します。普通、ここで例外に対処します。 +except (TypeError, NameError): + pass # もし必要なら、複数の種類の例外を一緒に処理できます。 +else: # try/except ブロックへのオプションの節。他の全てのexceptブロックより後に置かなければなりません。 + print("All good!") # tryで例外が発生しなかった場合のみ実行されます。 +finally: # 例外が発生したか、しなかったか、どのような例外だったかに関らず実行されます。 + print("We can clean up resources here") + +# try/finallyでリソースの始末をする代わりに、 with 文を使うこともできます。 +with open("myfile.txt") as f: + for line in f: + print(line) + +# Pythonは、iterableと呼ばれる基本的な抽象化が提供しています。 +# iterableは、シーケンスとして取り扱えるオブジェクトです。 +# range関数で返されるオブジェクトもiterableの一種です。 +filled_dict = {"one": 1, "two": 2, "three": 3} +our_iterable = filled_dict.keys() +print(our_iterable) # => dict_keys(['one', 'two', 'three']). これはiterableインタフェースを実装するオブジェクトです。 + +# iterableでループを行うことができます。 +for i in our_iterable: + print(i) # Prints one, two, three + +# しかし、インデックスで要素を参照することはできません。 +our_iterable[1] # TypeError が発生します。 + +# iterableは、iteratorの作り方がわかるオブジェクトです。 +our_iterator = iter(our_iterable) + +# iterator は、要素を取り出したときの状態を覚えるオブジェクトです。 +# "next()"により次の要素を取り出せます。 +next(our_iterator) # => "one" + +# 反復(iterate)する度に、状態を更新します。 +next(our_iterator) # => "two" +next(our_iterator) # => "three" + +# iteratorが自身の持つ全てのデータを返したあとは、 StopIteration 例外を発生させます。 +next(our_iterator) # StopIteration が発生します。 + +# "list()"を呼ぶことにより、iteratorの全ての要素を得られます。 +list(filled_dict.keys()) # => ["one", "two", "three"] + + +#################################################### +# 4. 関数 +#################################################### + +# 新しい関数を作成するには "def" を使います。 +def add(x, y): + print("x is {} and y is {}".format(x, y)) + return x + y # return 文で値を返します。 + +# 引数付きで関数を呼んでみましょう。 +add(5, 6) # => "x is 5 and y is 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) prints: + (1, 2) + {"a": 3, "b": 4} +""" + +# 関数を呼ぶとき、 args/kwargs の逆のことをすることができます! +# * を使ってタプルを展開したり、 ** を使って辞書を展開できます。 +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) に対応します。 + + +# タプルで複数の値を返す +def swap(x, y): # 括弧を使わずに、複数の値をタプルとして返すことができます。 + return y, x # (Note: 括弧は使わなくてもいいですが、使うこともできます。) + + +x = 1 +y = 2 +x, y = swap(x, y) # => x = 2, y = 1 +# (x, y) = swap(x,y) # このように、括弧は使っても使わなくてもいいです。 + + +# 関数のスコープ +x = 5 + + +def set_x(num): + # ローカル変数の x はグローバル変数の x とは異なります + x = num # => 43 + print(x) # => 43 + + +def set_global_x(num): + global x + print(x) # => 5 + x = num # グローバル変数の x に 6 が代入されました。 + print(x) # => 6 + +set_x(43) +set_global_x(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 +(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5 + +# 高階関数も組込まれています。 +list(map(add_10, [1, 2, 3])) # => [11, 12, 13] +list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3] + +list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [6, 7] + +# map や filter の代わりに、リスト内包表記を使うことができます。 +# リスト内包表記は、出力を別のリスト内包表記にネストさせることができます。 +[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] +[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7] + +# 集合(set)や辞書も内包表記ができます。 +{x for x in 'abcddeef' if x not in 'abc'} # => {'d', 'e', 'f'} +{x: x**2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} + + +#################################################### +# 5. モジュール +#################################################### + +# Pythonではモジュールをインポートできます。 +import math +print(math.sqrt(16)) # => 4.0 + +# モジュールの中から特定の関数をインポートすることもできます。 +from math import ceil, floor +print(ceil(3.7)) # => 4.0 +print(floor(3.7)) # => 3.0 + +# 全部の関数をモジュールからインポートすることができます。 +# Warning: この方法は推奨されません。 +from math import * + +# 短い名前でモジュールをインポートすることができます。 +import math as m +math.sqrt(16) == m.sqrt(16) # => True + +# Pythonのモジュールは実際には単なるPythonのファイルです。 +# 自分で書くことも、インポートすることもできます。 +# ファイル名がそのままモジュール名になります。 + +# モジュールで定義されている関数と属性を調べることができます。 +import math +dir(math) + +# もし、現在書いているスクリプトと同じフォルダに「math.py」という +# Pythonのスクリプトが存在する場合、そのmath.pyが +# 組み込みのPythonモジュールの代わりに読み込まれるでしょう。 +# これは、ローカルのフォルダはPythonの組み込みライブラリよりも +# 優先度が高いため発生するのです。 + + +#################################################### +# 6. クラス +#################################################### + +# クラスを作成するために、"class"という演算子を使います。 +class Human: + + # クラスの属性です。このクラスの全てのインスタンスで共有されます。 + species = "H. sapiens" + + # 標準的なイニシャライザで、このクラスがインスタンスを作成するときは毎回呼ばれます。 + # 2つのアンダースコアがオブジェクトや属性の前後についているとき、これらはPythonによって利用され、 + # ユーザーの名前空間には存在しないということに注意してください。 + # __init__ や __str__ 、 __repr__ のようなメソッド(やオブジェクト、属性)は、 + # magic methods (または dunder methods)と呼ばれます。 + # このような名前を自分で発明しないほうがよいでしょう。 + def __init__(self, name): + # 引数をインスタンスのname属性に設定します。 + self.name = name + + # プロパティの初期化 + self.age = 0 + + # インスタンスメソッド。全てのメソッドは"self"を最初の引数に取ります。 + def say(self, msg): + print("{name}: {message}".format(name=self.name, message=msg)) + + # 別のインスタンスメソッドの例。 + def sing(self): + return 'yo... yo... microphone check... one two... one two...' + + # クラスメソッドは全てのインスタンスで共有されます。 + # クラスメソッドではクラスを最初の引数として呼ばれます。 + @classmethod + def get_species(cls): + return cls.species + + # スタティックメソッドはクラスやインスタンスを参照せずに呼ばれます。 + @staticmethod + def grunt(): + return "*grunt*" + + # プロパティはgetterのようなものです。 + # age() メソッドを同名の読取専用属性に変換します。 + @property + def age(self): + return self._age + + # プロパティを設定できるようにします。 + @age.setter + def age(self, age): + self._age = age + + # プロパティを削除できるようにします。 + @age.deleter + def age(self): + del self._age + + +# Pythonインタプリタがソースファイルを読み込んだとき、全てのコードを実行します。 +# この __name__ による確認により、このモジュールがメインのプログラムである場合にのみ、 +# このコードブロックが実行されるようにします。 +if __name__ == '__main__': + # クラスのインスタンスを作成します。 + i = Human(name="Ian") + i.say("hi") # "Ian: hi" + j = Human("Joel") + j.say("hello") # "Joel: hello" + # i と j はHumanのインスタンスです。別の言葉で言うなら、これらはHumanのオブジェクトです。 + + # クラスメソッドを呼んでみましょう。 + i.say(i.get_species()) # "Ian: H. sapiens" + # 共有属性を変更してみましょう。 + Human.species = "H. neanderthalensis" + i.say(i.get_species()) # => "Ian: H. neanderthalensis" + j.say(j.get_species()) # => "Joel: H. neanderthalensis" + + # スタティックメソッドを呼んでみましょう。 + print(Human.grunt()) # => "*grunt*" + print(i.grunt()) # => "*grunt*" + + # インスタンスのプロパティを更新してみましょう。 + i.age = 42 + # プロパティを取得してみましょう。 + i.say(i.age) # => 42 + j.say(j.age) # => 0 + # プロパティを削除してみましょう。 + del i.age + # i.age # => AttributeError が発生します。 + + +#################################################### +# 6.1 多重継承 +#################################################### + +# 別のクラスを定義します。 +class Bat: + + species = 'Baty' + + def __init__(self, can_fly=True): + self.fly = can_fly + + # このクラスも say メソッドを持ちます。 + def say(self, msg): + msg = '... ... ...' + return msg + + # 同様に、独自のメソッドも与えましょう。 + def sonar(self): + return '))) ... (((' + +if __name__ == '__main__': + b = Bat() + print(b.say('hello')) + print(b.fly) + +# ファイル単位のモジュール化を利用するために、上記のクラスを別々のファイルに配置することができます。 +# ここでは、human.pyとbat.pyを作成してみましょう。 + +# 他のファイルから関数をインポートするために、次のような形式を利用してください。 +# from "拡張子無しのファイル名" import "関数またはクラス" + +# superhero.py +from human import Human +from bat import Bat + + +# BatmanはHumanとBatの両方を継承します。 +class Batman(Human, Bat): + + # Batmanは species のクラス属性に独自の値を持ちます。 + species = 'Superhero' + + def __init__(self, *args, **kwargs): + # 通常、属性を継承するにはsuper()を呼び出します。 + # super(Batman, self).__init__(*args, **kwargs) + # しかし、ここでは多重継承を行っているので、 super() はMRO(メソッド解決順序)の次の基本クラスにのみ動作します。 + # なので、全ての祖先に対して明示的に __init__ を呼ぶことにします。 + # *args と **kwargs を使うことで、それぞれの継承元が + # たまねぎの皮を剥がすごとく、引数を用いることができます。 + Human.__init__(self, 'anonymous', *args, **kwargs) + Bat.__init__(self, *args, can_fly=False, **kwargs) + # 名前の属性の値を上書きします。 + self.name = 'Sad Affleck' + + def sing(self): + return 'nan nan nan nan nan batman!' + + +if __name__ == '__main__': + sup = Batman() + + # インスタンスの型を調べてみましょう。 + if isinstance(sup, Human): + print('I am human') + if isinstance(sup, Bat): + print('I am bat') + if type(sup) is Batman: + print('I am Batman') + + # getattr() や super() の両方で使われるMROを取得します。 + # この属性は動的であり、更新が可能です。 + print(Batman.__mro__) # => (<class '__main__.Batman'>, <class 'human.Human'>, <class 'bat.Bat'>, <class 'object'>) + + # 親メソッドを呼び出しますが、独自のクラス属性を参照します。 + print(sup.get_species()) # => Superhero + + # オーバーロードされたメソッドを呼び出します。 + print(sup.sing()) # => nan nan nan nan nan batman! + + # 継承順により、Humanから継承されたメソッドを呼び出します。 + sup.say('I agree') # => Sad Affleck: I agree + + # 2番目の先祖にのみ存在するメソッドを呼び出してみます。 + print(sup.sonar()) # => ))) ... ((( + + # 継承されたクラス属性 + sup.age = 100 + print(sup.age) + + # デフォルト値が上書きされて、2番目の先祖から継承された属性 + print('Can I fly? ' + str(sup.fly)) + + +#################################################### +# 7. 発展的内容 +#################################################### + +# ジェネレータは遅延をするコードの作成に役立ちます。 +def double_numbers(iterable): + for i in iterable: + yield i + i + +# 次の値を処理するのに必要なデータしか読み込まないので、ジェネレータはメモリをあまり消費しません。 +# この性質により、他の方法では非常に多くのメモリを消費するような操作が可能になります。 +for i in double_numbers(range(1, 900000000)): # `range` もジェネレータの1つです。 + print(i) + if i >= 30: + break + +# リスト内包表記のように、ジェネータ内包表記を作成することもできます。 +values = (-x for x in [1, 2, 3, 4, 5]) +for x in values: + print(x) # prints -1 -2 -3 -4 -5 + +# ジェネレータ内包表記から直接リストを作成することもできます。 +values = (-x for x in [1, 2, 3, 4, 5]) +gen_to_list = list(values) +print(gen_to_list) # => [-1, -2, -3, -4, -5] + +# デコレータ +# この例では`beg` が `say` を `wraps`します。 +# もし 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, "Please! I am poor :(") + return msg + + return wrapper + + +@beg +def say(say_please=False): + msg = "Can you buy me a beer?" + return msg, say_please + + +print(say()) # Can you buy me a beer? +print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :( +``` + +## Ready For More? + +### Free Online + +* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com) +* [Ideas for Python Projects](http://pythonpracticeprojects.com) +* [The Official Docs](http://docs.python.org/3/) +* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/) +* [Python Course](http://www.python-course.eu/index.php) +* [First Steps With Python](https://realpython.com/learn/python-first-steps/) +* [A curated list of awesome Python frameworks, libraries and software](https://github.com/vinta/awesome-python) +* [30 Python Language Features and Tricks You May Not Know About](http://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html) +* [Official Style Guide for Python](https://www.python.org/dev/peps/pep-0008/) +* [Python 3 Computer Science Circles](http://cscircles.cemc.uwaterloo.ca/) +* [Dive Into Python 3](http://www.diveintopython3.net/index.html) +* [A Crash Course in Python for Scientists](http://nbviewer.jupyter.org/gist/anonymous/5924718) diff --git a/jquery.html.markdown b/jquery.html.markdown index d498733d..9326c74b 100644 --- a/jquery.html.markdown +++ b/jquery.html.markdown @@ -125,4 +125,4 @@ $('p').each(function() { }); -`` +``` diff --git a/julia.html.markdown b/julia.html.markdown index 5b3f6fd8..a3154f09 100644 --- a/julia.html.markdown +++ b/julia.html.markdown @@ -773,6 +773,6 @@ code_native(circle_area, (Float64,)) ## Further Reading -You can get a lot more detail from [The Julia Manual](http://docs.julialang.org/en/latest/manual/) +You can get a lot more detail from [The Julia Manual](http://docs.julialang.org/en/latest/#Manual-1) The best place to get help with Julia is the (very friendly) [mailing list](https://groups.google.com/forum/#!forum/julia-users). diff --git a/ko-kr/bash-kr.html.markdown b/ko-kr/bash-kr.html.markdown new file mode 100644 index 00000000..8e271d1f --- /dev/null +++ b/ko-kr/bash-kr.html.markdown @@ -0,0 +1,382 @@ +--- +category: tool +tool: bash +contributors: + - ["Max Yankov", "https://github.com/golergka"] + - ["Darren Lin", "https://github.com/CogBear"] + - ["Alexandre Medeiros", "http://alemedeiros.sdf.org"] + - ["Denis Arh", "https://github.com/darh"] + - ["akirahirose", "https://twitter.com/akirahirose"] + - ["Anton Strömkvist", "http://lutic.org/"] + - ["Rahil Momin", "https://github.com/iamrahil"] + - ["Gregrory Kielian", "https://github.com/gskielian"] + - ["Etan Reisner", "https://github.com/deryni"] + - ["Jonathan Wang", "https://github.com/Jonathansw"] + - ["Leo Rudberg", "https://github.com/LOZORD"] + - ["Betsy Lorton", "https://github.com/schbetsy"] + - ["John Detter", "https://github.com/jdetter"] +translators: + - ["Wooseop Kim", "https://github.com/linterpreteur"] +filename: LearnBash-kr.sh +lang: ko-kr +--- + +Bash는 유닉스 셸의 이름이며, 리눅스와 맥 OS X의 기본 셸로 그리고 GNU 운영체제를 위한 셸로서 배포되었습니다. +이하의 거의 모든 예시들은 셸 스크립트의 일부이거나 셸에서 바로 실행할 수 있습니다. + +[(영어) 이곳에서 더 알아보세요.](http://www.gnu.org/software/bash/manual/bashref.html) + +```bash +#!/bin/bash +# 스크립트의 첫 줄은 시스템에게 스크립트의 실행법을 알려주는 '셔뱅'입니다. +# https://ko.wikipedia.org/wiki/%EC%85%94%EB%B1%85 +# 이미 보았듯이 주석은 #으로 시작합니다. 셔뱅 또한 주석입니다. + +# 간단한 헬로 월드 +echo 헬로 월드! + +# 각각의 명령어는 개행 혹은 세미콜론 이후에 시작됩니다. +echo '첫번째 줄'; echo '두번째 줄' + +# 변수 선언은 다음과 같습니다. +Variable="어떤 문자열" + +# 하지만 다음은 틀린 형태입니다. +Variable = "어떤 문자열" +# Bash는 Variable이 실행해야 하는 명령어라고 판단할 것이고, 해당 명령어를 찾을 +# 수 없기 때문에 에러를 발생시킬 것입니다. + +# 다음도 같습니다. +Variable= '어떤 문자열' +# Bash는 '어떤 문자열'이 실행해야 하는 명령어라고 판단하여 에러를 발생시킬 것입니다. +# (이 경우에 'Variable=' 부분은 '어떤 문자열' 명령어의 스코프에서만 유효한 +# 변수 할당으로 해석됩니다.) + +# 변수 사용은 다음과 같습니다. +echo $Variable +echo "$Variable" +echo '$Variable' +# 할당, 내보내기 등 변수 자체를 사용할 때에는 $ 없이 이름을 적습니다. +# 변수의 값을 사용할 때에는 $를 사용해야 합니다. +# 작은 따옴표는 변수를 확장시키지 않는다는 사실에 주의하세요. +# (역자 주: '$Variable'은 변수 Variable의 값이 아닌 문자열 "$Variable"입니다.) + +# 인수 확장은 ${ }입니다. +echo ${Variable} +# 이는 인수 확장의 간단한 예시입니다. +# 인수 확장은 변수로부터 값을 받아 그 값을 "확장"하거나 출력합니다. +# 확장을 통해 인수나 그 값이 변경될 수 있습니다. +# 이하는 확장에 대한 다른 예시들입니다. + +# 변수에서의 문자열 치환 +echo ${Variable/Some/A} +# 처음으로 나타나는 "Some"를 "A"로 치환합니다. + +# 변수의 부분열 +Length=7 +echo ${Variable:0:Length} +# 변수 값에서 처음 7개 문자만을 반환합니다. + +# 변수의 기본값 +echo ${Foo:-"Foo가_없거나_비어_있을_때의_기본값"} +# null(Foo=) 값이나 빈 문자열(Foo="")일 경우에만 작동합니다. 0은 (Foo=0)은 0입니다. +# 기본값을 반환할 뿐 변수 값을 변경하지는 않는다는 사실에 주목하세요. + +# 중괄호 확장 { } +# 임의의 문자열을 생성합니다. +echo {1..10} +echo {a..z} +# 시작 값으로부터 끝 값까지의 범위를 출력합니다. + +# 내장 변수 +# 유용한 내장 변수들이 있습니다. +echo "마지막 프로그램의 반환값: $?" +echo "스크립트의 PID: $$" +echo "스크립트에 넘겨진 인자의 개수: $#" +echo "스크립트에 넘겨진 모든 인자: $@" +echo "각각 변수로 쪼개진 스크립트 인자: $1 $2..." + +# echo와 변수의 사용법을 알게 되었으니, +# bash의 기초를 조금 더 배워봅시다! + +# 현재 디렉토리는 `pwd` 명령어로 알 수 있습니다. +# `pwd`는 "print working directory(작업 디렉토리 출력)"의 약자입니다. +# 내장 변수`$PWD`를 사용할 수도 있습니다. +# 이하는 모두 동일합니다. +echo "I'm in $(pwd)" # `pwd`를 실행하여 문자열에 보간 +echo "I'm in $PWD" # 변수를 보간 + +# 터미널이나 결과의 출력물이 너무 많다면 +# 명령어 `clear`를 이용해 화면을 지울 수 있습니다. +clear +# 컨트롤+L 또한 화면을 지울 수 있습니다. + +# 입력 값 읽기 +echo "이름이 뭐에요?" +read Name # 변수 선언이 필요 없다는 데 주목하세요. +echo $Name님, 안녕하세요! + +# 평범한 if 구조도 있습니다. +# 'man test'로 조건문에 대해 더 알아보세요. +if [ $Name != $USER ] +then + echo "사용자가 아닙니다." +else + echo "사용자입니다." +fi + +# $Name이 비어 있다면, bash는 위의 조건을 다음과 같이 인식합니다. +if [ != $USER ] +# 이는 문법적으로 유효하지 않습니다. +# 따라서 bash에서 비어 있을 수 있는 변수를 "안전하게" 사용하는 법은 다음과 같습니다. +if [ "$Name" != $USER ] ... +# $Name이 비어 있다면 bash는 +if [ "" != $USER ] ... +# 와 같이 인식하여 예상한 대로 동작합니다. + +# 조건부 실행도 있습니다. +echo "항상 실행" || echo "첫 명령어가 실패해야 실행" +echo "항상 실행" && echo "첫 명령어가 실패하지 않아야 실행" + +# if문과 함께 &&와 ||을 사용하려면, 대괄호가 여러 쌍 필요합니다. +if [ "$Name" == "철수" ] && [ "$Age" -eq 15 ] +then + echo "$Name이 철수이고 $Age가 15일 때 실행" +fi + +if [ "$Name" == "민희" ] || [ "$Name" == "상민" ] +then + echo "$Name이 민희이거나 상민일 때 실행" +fi + +# 표현식은 다음 형식으로 표기됩니다. +echo $(( 10 + 5 )) + +# 다른 프로그래밍 언어와는 달리, bash는 셸이기 때문에 현재 디렉토리의 컨텍스트에서 +# 실행됩니다. 현재 디렉토리의 파일과 디렉토리를 ls 명령어로 나열할 수 있습니다. +ls + +# 다음은 실행을 제어하는 옵션의 예시입니다. +ls -l # 모든 파일과 디렉토리를 분리된 줄에 나열 +ls -t # 디렉토리 내용을 마지막으로 수정된 날짜(내림차순)에 따라 정렬 +ls -R # 이 디렉토리와 그 안의 모든 디렉토리에 대해 재귀적으로 `ls` 실행 + +# 이전 명령어의 결과는 다음 명령어에 입력될 수 있습니다. +# grep 명령어는 입력을 주어진 패턴에 따라 필터링합니다. 다음은 현재 디렉토리의 +# .txt 파일을 나열하는 방법입니다. +ls -l | grep "\.txt" + +# `cat`을 이용해 stdout으로 파일을 출력합니다. +cat file.txt + +# `cat`으로 파일을 읽을 수도 있습니다. +Contents=$(cat file.txt) +echo "파일 시작\n$Contents\n파일 끝" + +# `cp`를 이용해 파일이나 디렉토리를 다른 곳으로 복사할 수 있습니다. +# `cp`는 원본의 새로운 버전을 생성하므로 사본을 편집하는 것은 +# 원본에 영향을 주지 않으며 그 반대도 마찬가지입니다. +# 목표 위치에 이미 파일이 있다면 덮어쓰게 됩니다. +cp srcFile.txt clone.txt +cp -r srcDirectory/ dst/ # 재귀적으로 복사 + +# 컴퓨터 간에 파일을 공유하려고 한다면 `scp` 혹은 `sftp`를 사용합니다. +# `scp`는 `cp`와 매우 유사하게 동작하며 +# `sftp`는 더 상호작용적입니다. + +# `mv`로 파일 혹은 디렉토리를 다른 곳으로 이동합니다. +# `mv`는 `cp`와 유사하지만 원본을 삭제합니다. +# 또한 `mv`로 파일의 이름을 바꿀 수도 있습니다. +mv s0urc3.txt dst.txt # sorry, l33t hackers... + +# bash는 현재 디렉토리의 컨텍스트에서 실행되기 때문에, 다른 디렉토리에서 명령어를 +# 실행하고 싶으실 수 있습니다. cd를 이용해 위치를 변경합니다. +cd ~ # 홈 디렉토리로 변경 +cd .. # 한 디렉토리 위로 이동 + # (즉 /home/username/Downloads에서 /home/username로) +cd /home/username/Documents # 특정 디렉토리로 이동 +cd ~/Documents/.. # 아직도 홈 디렉토리... 아닌가?? + +# 서브셸로 디렉토리를 넘어서 작업할 수도 있습니다. +(echo "처음엔 여기 $PWD") && (cd 어딘가; echo "이제는 여기 $PWD") +pwd # 아직도 첫 디렉토리에 있음 + +# `mkdir`로 새 디렉토리를 만듭니다. +mkdir myNewDir +# `-p` 플래그는 필요하다면 해당 디렉토리의 경로 중간에 있는 디렉토리를 생성합니다. +mkdir -p myNewDir/with/intermediate/directories + +# (stdin, stdout, stderr로) 명령어의 입출력을 리디렉션할 수 있습니다. +# stdin의 내용을 ^EOF$까지 읽고 hello.py에 그 내용을 덮어씁니다. +cat > hello.py << EOF +#!/usr/bin/env python +from __future__ import print_function +import sys +print("#stdout", file=sys.stdout) +print("#stderr", file=sys.stderr) +for line in sys.stdin: + print(line, file=sys.stdout) +EOF + +# stdin, stdoutk, stderr을 다양한 방법으로 리디렉션하여 hello.py를 실행합니다. +python hello.py < "input.in" +python hello.py > "output.out" +python hello.py 2> "error.err" +python hello.py > "output-and-error.log" 2>&1 +python hello.py > /dev/null 2>&1 +# 출력 오류는 이미 파일이 있을 경우 덮어쓰지만, +# 덮어쓰는 대신에 내용에 추가하고 싶다면 ">>"를 사용합니다. +python hello.py >> "output.out" 2>> "error.err" + +# output.out에 덮어쓰고, error.err에 추가하고, 줄을 세기 +info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err +wc -l output.out error.err + +# 명령어를 실행하고 그 파일 디스크립터를 출력 (예: /dev/fd/123) +# man fd 참고 +echo <(echo "#helloworld") + +# output.out을 "#helloworld"으로 덮어쓰기 +cat > output.out <(echo "#helloworld") +echo "#helloworld" > output.out +echo "#helloworld" | cat > output.out +echo "#helloworld" | tee output.out >/dev/null + +# 임시 파일을 지울 수 있습니다. ('-i'로 대화식 실행) +# 경고: `rm` 명령어는 되돌릴 수 없습니다. +rm -v output.out error.err output-and-error.log +rm -r tempDir/ # 재귀적으로 삭제 + +# 다른 명령어에서 $()을 이용해 명령어를 치환할 수도 있습니다. +# 다음 명령어는 현재 디렉토리의 파일 및 디렉토리의 수를 표시합니다. +echo "$(ls | wc -l)개 항목이 있습니다." + +# 백틱(``)을 이용할 수도 있지만 이 방식을 이용하면 중첩할 수 없기 때문에 +# $()을 사용하는 것이 더 좋습니다. +echo "`ls | wc -l`개 항목이 있습니다." + +# 자바나 C++의 switch와 비슷하게 동작하는 case 문을 사용할 수 있습니다. +case "$Variable" in + # 충족시킬 조건을 나열 + 0) echo "0입니다.";; + 1) echo "1입니다.";; + *) echo "널이 아닌 값입니다.";; +esac + +# for 반복문은 주어진 인자만큼 반복합니다. +# 다음은 $Variable을 세 번 출력합니다. +for Variable in {1..3} +do + echo "$Variable" +done + +# 혹은 "전통적인 for 반복문" 방식을 쓸 수도 있습니다. +for ((a=1; a <= 3; a++)) +do + echo $a +done + +# 파일에도 적용될 수 있습니다. +# 다음은 file1과 file2에 'cat' 명령어를 실행합니다. +for Variable in file1 file2 +do + cat "$Variable" +done + +# 혹은 명령어의 결과에도 이용할 수 있습니다. +# 다음은 ls의 결과를 cat합니다. +for Output in $(ls) +do + cat "$Output" +done + +# while 반복문 +while [ true ] +do + echo "반복문 몸체" + break +done + +# 함수를 정의할 수도 있습니다. +# 정의: +function foo () +{ + echo "인자는 함수 인자처럼 작동합니다. $@" + echo "그리고 $1 $2..." + echo "함수입니다." + return 0 +} + +# 혹은 단순하게 +bar () +{ + echo "함수를 선언하는 다른 방법" + return 0 +} + +# 함수 호출 +foo "My name is" $Name + +# 몇 가지 유용한 명령어를 알아두면 좋습니다. +# file.txt의 마지막 10줄 출력 +tail -n 10 file.txt +# file.txt의 첫 10줄 출력 +head -n 10 file.txt +# file.txt 줄 별로 정렬 +sort file.txt +# 중복되는 줄을 생략하거나 -d를 이용하여 보고 +uniq -d file.txt +# ',' 문자 이전의 첫 열만 출력 +cut -d ',' -f 1 file.txt +# file.txt에서 'okay'를 모두 'great'로 교체 (정규식 호환) +sed -i 's/okay/great/g' file.txt +# file.txt에서 정규식에 맞는 모든 줄을 stdin에 출력 +# 다음 예시는 "foo"로 시작해 "bar"로 끝나는 줄 출력 +grep "^foo.*bar$" file.txt +# "-c" 옵션을 넘겨 줄 번호를 대신 출력 +grep -c "^foo.*bar$" file.txt +# 다른 유용한 옵션 +grep -r "^foo.*bar$" someDir/ # 재귀적으로 `grep` +grep -n "^foo.*bar$" file.txt # 줄 번호 매기기 +grep -rI "^foo.*bar$" someDir/ # 재귀적으로 `grep`하되 바이너리 파일은 무시 +# 같은 검색으로 시작하여 "baz"를 포함하는 줄만 필터 +grep "^foo.*bar$" file.txt | grep -v "baz" + +# 정규식이 아니라 문자열로 검색하고 싶다면 +# fgrep 혹은 grep -F +fgrep "foobar" file.txt + +# trap 명령어로 스크립트에서 신호를 받을 때 명령어를 실행할 수 있습니다. +# 다음 명령어는 셋 중 한 가지 신호를 받으면 rm 명령어를 실행합니다. +trap "rm $TEMP_FILE; exit" SIGHUP SIGINT SIGTERM + +# `sudo`를 통해 슈퍼이용자로 명령어를 실행합니다. +NAME1=$(whoami) +NAME2=$(sudo whoami) +echo "$NAME1였다가 더 강한 $NAME2가 되었다" + +# 'help' 명령어로 내장 문서를 읽을 수 있습니다. +help +help help +help for +help return +help source +help . + +# man으로 매뉴얼을 읽을 수도 있습니다. +apropos bash +man 1 bash +man bash + +# info 명령어로 문서를 읽습니다. (?로 도움말) +apropos info | grep '^info.*(' +man info +info info +info 5 info + +# bash의 info 문서를 읽어 보세요. +info bash +info bash 'Bash Features' +info bash 6 +info --apropos bash +``` diff --git a/ko-kr/kotlin-kr.html.markdown b/ko-kr/kotlin-kr.html.markdown new file mode 100644 index 00000000..9b2294d4 --- /dev/null +++ b/ko-kr/kotlin-kr.html.markdown @@ -0,0 +1,376 @@ +--- +language: kotlin +contributors: + - ["S Webber", "https://github.com/s-webber"] +translators: + - ["Alan Jeon", "https://github.com/skyisle"] +lang: ko-kr +filename: LearnKotlin-kr.kt +--- + +Kotlin 은 정적 타입 프로그래밍 언어로 JVM, 안드로이드, 브라우져를 지원하며 Java 와 100% 상호 운용이 가능합니다. +[자세한 내용은 다음을 참고하세요.](https://kotlinlang.org/) + +```kotlin +// 한 줄짜리 주석은 // 로 시작합니다. +/* +여러 줄 주석은 이와 같이 표시합니다. +*/ + +// "package" 예약어는 자바와 동일하게 사용됩니다. +package com.learnxinyminutes.kotlin + +/* +Kotlin 프로그램의 진입점은 main 이라는 함수명으로 지정됩니다. +이 함수에 명령행 인수가 배열로 전달됩니다. +*/ +fun main(args: Array<String>) { + /* + 값을 선언할때는 "var" 또는 "val"이 사용됩니다. + "var"와는 다르게 "val"로 선언된 변수에는 값을 재할당 할 수 없습니다. + */ + val fooVal = 10 // fooVal 에 다른 값을 다시 할당 할 수 없습니다. + var fooVar = 10 + fooVar = 20 // fooVar 에는 선언 이후에도 다른 값을 할당 할 수 있습니다 + + /* + 대부분의 경우, Kotlin 에서는 변수 타입을 판단할 수 있기때문에 명시적으로 지정해 주지 않을 수 있습니다. + 다음과 같이 변수의 타입을 명시적으로 지정할 수 있습니다. + */ + val foo : Int = 7 + + /* + 문자형은 Java와 비슷하게 표시될 수 있습니다. + 이스케이핑에는 백슬래시를 사용합니다. + */ + val fooString = "My String Is Here!" + val barString = "Printing on a new line?\nNo Problem!" + val bazString = "Do you want to add a tab?\tNo Problem!" + println(fooString) + println(barString) + println(bazString) + + /* + Raw 문자열은 쌍따옴표 3개(""")로 표기합니다. + Raw 문자열에는 줄바꿈이나 모든 다른 문자들을 사용할 수 있습니다. + */ + val fooRawString = """ +fun helloWorld(val name : String) { + println("Hello, world!") +} +""" + println(fooRawString) + + /* + 문자열은 템플릿 표현식을 포함할 수 있습니다. + 템플릿은 달러 기호($)로 시작합니다. + */ + val fooTemplateString = "$fooString has ${fooString.length} characters" + println(fooTemplateString) + + /* + 변수가 null 값을 가지려면 이를 명시적으로 선언해야 합니다. + 변수 선언시 타입에 ? 표시를 붙여 nullable 을 표시합니다. + ?. 연산자를 사용해 nullable 변수에 접근합니다. + ?: 연산자를 이용해서 변수 값이 null 일때 사용할 값을 지정합니다. + */ + var fooNullable: String? = "abc" + println(fooNullable?.length) // => 3 + println(fooNullable?.length ?: -1) // => 3 + fooNullable = null + println(fooNullable?.length) // => null + println(fooNullable?.length ?: -1) // => -1 + + /* + 함수는 "fun" 예약어를 사용해 선언합니다. + 함수명 이후 괄호 안에 인자를 기술합니다. + 함수 인자에 기본 값을 지정할 수도 있습니다. + 함수에 리턴값이 있을 때, 필요한 경우 인자 뒤에 타입을 명시합니다. + */ + fun hello(name: String = "world"): String { + return "Hello, $name!" + } + println(hello("foo")) // => Hello, foo! + println(hello(name = "bar")) // => Hello, bar! + println(hello()) // => Hello, world! + + /* + 함수에 가변 인자를 넘기려면 인자에 "vararg" 예약어를 사용합니다. + */ + fun varargExample(vararg names: Int) { + println("Argument has ${names.size} elements") + } + varargExample() // => 인자가 0개 인 경우 + varargExample(1) // => 인자가 1개인 경우 + varargExample(1, 2, 3) // => 인자가 3개인 경우 + + /* + 함수가 단일 표현식으로 이루어진 경우에 중괄호를 생략할 수 있습니다. + 이때 함수 구현부는 = 기호 이후에 기술합니다. + */ + fun odd(x: Int): Boolean = x % 2 == 1 + println(odd(6)) // => false + println(odd(7)) // => true + + // 리턴 타입이 유추 가능한 경우 이를 명시하지 않아도 됩니다. + fun even(x: Int) = x % 2 == 0 + println(even(6)) // => true + println(even(7)) // => false + + // 함수는 함수를 인자를 받을 수 있고 함수를 리턴할 수 있습니다. + fun not(f: (Int) -> Boolean): (Int) -> Boolean { + return {n -> !f.invoke(n)} + } + // 함수는 :: 연산자를 사용해서 다른 함수에 인자로 넘길 수 있습니다. + val notOdd = not(::odd) + val notEven = not(::even) + // 람다식을 인자로 사용할 수 있습니다. + val notZero = not {n -> n == 0} + /* + 하나의 인자를 가지는 람다식의 선언부와 -> 연산자는 생략될 수 있습니다. + 이때 그 인자명은 it로 지정됩니다. + */ + val notPositive = not {it > 0} + for (i in 0..4) { + println("${notOdd(i)} ${notEven(i)} ${notZero(i)} ${notPositive(i)}") + } + + // "class" 예약어는 클래스를 선언할 때 사용됩니다. + class ExampleClass(val x: Int) { + fun memberFunction(y: Int): Int { + return x + y + } + + infix fun infixMemberFunction(y: Int): Int { + return x * y + } + } + /* + 새로운 객체를 생성하기 위해서는 생성자를 바로 호출합니다. + Kotlin 에서는 new 예약어가 없다는 걸 기억하세요. + */ + val fooExampleClass = ExampleClass(7) + // 맴버 함수는 dot 표기로 호출할 수 있습니다. + println(fooExampleClass.memberFunction(4)) // => 11 + /* + 함수 선언에 "infix" 예약어를 사용하면 이 함수를 중위 표현식(infix notation)으로 호출할 수 있습니다 + */ + println(fooExampleClass infixMemberFunction 4) // => 28 + + /* + 데이터 클래스로 데이터만을 가지고 있는 클래스를 손쉽게 선언할 수 있습니다. + "hashCode"/"equals" 와 "toString" 는 자동으로 생성됩니다. + */ + data class DataClassExample (val x: Int, val y: Int, val z: Int) + val fooData = DataClassExample(1, 2, 4) + println(fooData) // => DataClassExample(x=1, y=2, z=4) + + // 데이터 클래스는 copy 함수를 가지고 있습니다. + val fooCopy = fooData.copy(y = 100) + println(fooCopy) // => DataClassExample(x=1, y=100, z=4) + + // 객체를 여러 변수로 분리할 수 있습니다. + val (a, b, c) = fooCopy + println("$a $b $c") // => 1 100 4 + + // "for" 루프에서 변수 분리 하기 + for ((a, b, c) in listOf(fooData)) { + println("$a $b $c") // => 1 100 4 + } + + val mapData = mapOf("a" to 1, "b" to 2) + // Map.Entry 또한 키와 값으로 분리가 가능합니다. + for ((key, value) in mapData) { + println("$key -> $value") + } + + // "with" 함수는 JavaScript 의 "with" 구문과 비슷하게 사용됩니다. + data class MutableDataClassExample (var x: Int, var y: Int, var z: Int) + val fooMutableDate = MutableDataClassExample(7, 4, 9) + with (fooMutableDate) { + x -= 2 + y += 2 + z-- + } + println(fooMutableDate) // => MutableDataClassExample(x=5, y=6, z=8) + + /* + "listOf" 함수로 리스트를 만들 수 있습니다. + 리스트는 변경 불가능(immutable)하게 만들어져 항목의 추가 삭제가 불가능합니다. + */ + val fooList = listOf("a", "b", "c") + println(fooList.size) // => 3 + println(fooList.first()) // => a + println(fooList.last()) // => c + // 각 항목은 인덱스로 접근이 가능합니다. + println(fooList[1]) // => b + + // 변경가능한(mutable) 리스트는 "mutableListOf" 함수로 만들 수 있습니다. + val fooMutableList = mutableListOf("a", "b", "c") + fooMutableList.add("d") + println(fooMutableList.last()) // => d + println(fooMutableList.size) // => 4 + + // 집합(set)은 "setOf" 함수로 만들 수 있습니다. + val fooSet = setOf("a", "b", "c") + println(fooSet.contains("a")) // => true + println(fooSet.contains("z")) // => false + + // 맵은 "mapOf" 함수로 만들 수 있습니다. + val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9) + // 맵은 키를 통해 그 값에 접근할 수 있습니다. Map values can be accessed by their key. + println(fooMap["a"]) // => 8 + + /* + 시퀀스는 지연 평가되는 컬랙션을 말합니다. Sequences represent lazily-evaluated collections. + "generateSequence" 를 사용해 시퀀스를 만들 수 있습니다. We can create a sequence using the "generateSequence" function. + */ + val fooSequence = generateSequence(1, { it + 1 }) + val x = fooSequence.take(10).toList() + println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + + // 다음은 시퀀스를 사용해서 피보나치 수열을 생성하는 예입니다. + fun fibonacciSequence(): Sequence<Long> { + var a = 0L + var b = 1L + + fun next(): Long { + val result = a + b + a = b + b = result + return a + } + + return generateSequence(::next) + } + val y = fibonacciSequence().take(10).toList() + println(y) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] + + // Kotlin 은 컬랙션에서 사용할 수 있는 고차(higher-order)함수를 제공합니다. + val z = (1..9).map {it * 3} + .filter {it < 20} + .groupBy {it % 2 == 0} + .mapKeys {if (it.key) "even" else "odd"} + println(z) // => {odd=[3, 9, 15], even=[6, 12, 18]} + + // "for" 루프는 이터레이터를 제공하는 어떤 것과도 함께 사용할 수 있습니다. + for (c in "hello") { + println(c) + } + + // "while" 루프는 다른 언어들과 동일하게 사용됩니다. + var ctr = 0 + while (ctr < 5) { + println(ctr) + ctr++ + } + do { + println(ctr) + ctr++ + } while (ctr < 10) + + /* + "if"는 값을 리턴하는 표현으로 사용될 수 있습니다. + 그래서 Kotlin 에서는 삼항 ?: 연산자가 필요하지 않습니다. + */ + val num = 5 + val message = if (num % 2 == 0) "even" else "odd" + println("$num is $message") // => 5 is odd + + // "when"은 "if-else if" 를 대체할때 사용할 수 있습니다. + val i = 10 + when { + i < 7 -> println("first block") + fooString.startsWith("hello") -> println("second block") + else -> println("else block") + } + + // "when"은 인수와 함께 사용될 수 있습니다. + when (i) { + 0, 21 -> println("0 or 21") + in 1..20 -> println("in the range 1 to 20") + else -> println("none of the above") + } + + // "when"은 값을 리턴하는 함수처럼 사용될 수 있습니다. + var result = when (i) { + 0, 21 -> "0 or 21" + in 1..20 -> "in the range 1 to 20" + else -> "none of the above" + } + println(result) + + /* + 객체가 어떤 타입인지를 확인하기 위해 "is" 연산자를 사용할 수 있습니다. + 타입 체크를 통과하면 객체의 명시적인 형변환 없이도 그 타입 값으로 사용될 수 있습니다. + 이를 스마트 변환(Smartcast)이라 부릅니다. + */ + fun smartCastExample(x: Any) : Boolean { + if (x is Boolean) { + // x is automatically cast to Boolean + return x + } else if (x is Int) { + // x is automatically cast to Int + return x > 0 + } else if (x is String) { + // x is automatically cast to String + return x.isNotEmpty() + } else { + return false + } + } + println(smartCastExample("Hello, world!")) // => true + println(smartCastExample("")) // => false + println(smartCastExample(5)) // => true + println(smartCastExample(0)) // => false + println(smartCastExample(true)) // => true + + // 스마트 변환은 when 블럭과도 함께 사용됩니다. + fun smartCastWhenExample(x: Any) = when (x) { + is Boolean -> x + is Int -> x > 0 + is String -> x.isNotEmpty() + else -> false + } + + /* + 확장(Extensions)을 이용해 클래스에 새로운 기능을 추가할 수 있습니다. + C#에서의 확장 매서드와 유사합니다. + */ + fun String.remove(c: Char): String { + return this.filter {it != c} + } + println("Hello, world!".remove('l')) // => Heo, word! + + println(EnumExample.A) // => A + println(ObjectExample.hello()) // => hello +} + +// Enum 클래스는 자바의 enum 타입과 유사합니다. +enum class EnumExample { + A, B, C +} + +/* +"object" 예약어는 싱클톤 객체를 생성할 때 사용됩니다. +객체를 새로 생성할 수는 없지만 이름을 가지고 접근해 사용할 수 있습니다. +이는 스칼라의 싱글톤 객체와 유사합니다. +*/ +object ObjectExample { + fun hello(): String { + return "hello" + } +} + +fun useObject() { + ObjectExample.hello() + val someRef: Any = ObjectExample // 객체의 이름을 그대로 사용합니다. +} + +``` + +### 더 알아보기 + +* [Kotlin tutorials (EN)](https://kotlinlang.org/docs/tutorials/) +* [Try Kotlin in your browser (EN)](http://try.kotlinlang.org/) +* [A list of Kotlin resources (EN)](http://kotlin.link/) diff --git a/ko-kr/vim-kr.html.markdown b/ko-kr/vim-kr.html.markdown new file mode 100644 index 00000000..a4cb32ec --- /dev/null +++ b/ko-kr/vim-kr.html.markdown @@ -0,0 +1,235 @@ +--- +category: tool +tool: vim +contributors: + - ["RadhikaG", "https://github.com/RadhikaG"] +translators: + - ["Wooseop Kim", "https://github.com/linterpreteur"] +filename: LearnVim-kr.txt +lang: ko-kr +--- + +[Vim](www.vim.org) +(Vi IMproved)은 유닉스의 인기 있는 vi 에디터의 클론입니다. Vim은 속도와 생산성을 위해 +설계된 텍스트 에디터로, 대부분의 유닉스 기반 시스템에 내장되어 있습니다. 다양한 단축 키를 통해 +파일 안에서 빠르게 이동하고 편집할 수 있습니다. + +## Vim 조작의 기본 + +``` + vim <filename> # vim으로 <filename> 열기 + :q # vim 종료 + :w # 현재 파일 저장 + :wq # 파일 저장 후 종료 + :q! # 저장하지 않고 종료 + # ! *강제로* :q를 실행하여, 저장 없이 종료 + :x # 파일 저장 후 종료 (짧은 :wq) + + u # 동작 취소 + CTRL+R # 되돌리기 + + h # 한 글자 왼쪽으로 이동 + j # 아래로 한 줄 이동 + k # 위로 한 줄 이동 + l # 한 글자 오른쪽으로 이동 + + # 줄 안에서의 이동 + + 0 # 줄 시작으로 이동 + $ # 줄 끝으로 이동 + ^ # 줄의 공백이 아닌 첫 문자로 이동 + + # 텍스트 검색 + + /word # 커서 뒤에 나타나는 해당 단어를 모두 하이라이트 + ?word # 커서 앞에 나타나는 해당 단어를 모두 하이라이트 + n # 해당 단어를 검색 후 다음으로 나타나는 위치로 이동 + N # 이전에 나타나는 위치로 이동 + + :%s/foo/bar/g # 파일 모든 줄에 있는 'foo'를 'bar'로 치환 + :s/foo/bar/g # 현재 줄에 있는 'foo'를 'bar'로 치환 + + # 문자로 이동 + + f<character> # <character>로 건너뛰기 + t<character> # <character>의 바로 뒤로 건너뛰기 + + # 예를 들어, + f< # <로 건너뛰기 + t< # <의 바로 뒤로 건너뛰기 + + # 단어 단위로 이동 + + w # 한 단어 오른쪽으로 이동 + b # 한 단어 왼쪽으로 이동 + e # 현재 단어의 끝으로 이동 + + # 기타 이동 명령어 + + gg # 파일 맨 위로 이동 + G # 파일 맨 아래로 이동 + :NUM # 줄 수 NUM(숫자)로 가기 + H # 화면 꼭대기로 이동 + M # 화면 중간으로 이동 + L # 화면 바닥으로 이동 +``` + +## 모드 + +Vim은 **모드**의 개념에 기초를 두고 있습니다. + +명령어 모드 - vim을 시작하면 처음에 이 모드입니다. 이동과 명령어 입력에 사용합니다. +삽입 모드 - 파일을 수정합니다. +비주얼 모드 - 텍스트를 하이라이트하고 그 텍스트에 대한 작업을 합니다. +실행 모드 - ':' 이후 명령어를 입력합니다. + +``` + i # 커서 위치 앞에서 삽입 모드로 변경 + a # 커서 위치 뒤에서 삽입 모드로 변경 + v # 비주얼 모드로 변경 + : # 실행 모드로 변경 + <esc> # 현재 모드를 벗어나 명령어 모드로 변경 + + # 복사와 붙여넣기 + + y # 선택한 객체 복사(Yank) + yy # 현재 줄 복사 + d # 선택한 객체 삭제 + dd # 현재 줄 삭제 + p # 커서 위치 뒤에 복사한 텍스트 붙여넣기 + P # 커서 위치 뒤에 복사한 텍스트 붙여넣기 + x # 현재 커서 위치의 문자 삭제 +``` + +## vim의 문법 + +Vim의 명령어는 '서술어-수식어-목적어'로 생각할 수 있습니다. + +서술어 - 취할 동작 +수식어 - 동작을 취할 방식 +목적어 - 동작을 취할 객체 + +'서술어', '수식어', '목적어'의 예시는 다음과 같습니다. + +``` + # '서술어' + + d # 지운다 + c # 바꾼다 + y # 복사한다 + v # 선택한다 + + # '수식어' + + i # 안에 + a # 근처에 + NUM # (숫자) + f # 찾아서 그곳에 + t # 찾아서 그 앞에 + / # 문자열을 커서 뒤로 찾아서 + ? # 문자열을 커서 앞으로 찾아서 + + # '목적어' + + w # 단어를 + s # 문장을 + p # 문단을 + b # 블락을 + + # 예시 '문장' (명령어) + + d2w # 단어 2개를 지운다 + cis # 문장 안을 바꾼다 + yip # 문단 안을 복사한다 + ct< # 여는 괄호까지 바꾼다 + # 현재 위치에서 다음 여는 괄호까지의 텍스트를 바꾼다 + d$ # 줄 끝까지 지운다 +``` + +## 몇 가지 트릭 + + <!--TODO: Add more!--> +``` + > # 선택한 영역 한 칸 들여쓰기 + < # 선택한 영역 한 칸 내어쓰기 + :earlier 15m # 15분 전의 상태로 되돌리기 + :later 15m # 위의 명령어를 취소 + ddp # 이어지는 줄과 위치 맞바꾸기 (dd 후 p) + . # 이전 동작 반복 + :w !sudo tee % # 현재 파일을 루트 권한으로 저장 +``` + +## 매크로 + +매크로는 기본적으로 녹화할 수 있는 동작을 말합니다. +매크로를 녹화하기 시작하면, 끝날 때까지 **모든** 동작과 명령어가 녹화됩니다. +매크로를 호출하면 선택한 텍스트에 대해 정확히 같은 순서의 동작과 명령어가 실행됩니다. + +``` + qa # 'a'라는 이름의 매크로 녹화 시작 + q # 녹화 중지 + @a # 매크로 실행 +``` + +### ~/.vimrc 설정 + +.vimrc 파일은 Vim이 시작할 때의 설정을 결정합니다. + +다음은 ~/.vimrc 파일의 예시입니다. + +``` +" ~/.vimrc 예시 +" 2015.10 + +" vim이 iMprove 되려면 필요 +set nocompatible + +" 자동 들여쓰기 등을 위해 파일 명으로부터 타입 결정 +filetype indent plugin on + +" 신택스 하이라이팅 켜기 +syntax on + +" 커맨드 라인 완성 향상 +set wildmenu + +" 대문자를 썼을 때가 아니면 대소문자 구분하지 않고 검색 +set ignorecase +set smartcase + +" 줄넘김을 했을 때 파일에 따른 들여쓰기가 켜져 있지 않다면 +" 현재 줄과 같은 들여쓰기를 유지 +set autoindent + +" 좌측에 줄 번호 표시 +set number + +" 들여쓰기 설정 (개인 기호에 따라 변경) + +" 탭 하나와 시각적으로 같을 스페이스 개수 +set tabstop=4 + +" 편집할 때 탭 하나에 들어갈 스페이스 수 +set softtabstop=4 + +" 들여쓰기 혹은 내어쓰기 작업(>>, <<)을 했을 때 움직일 스페이스 개수 +set shiftwidth=4 + +" 탭을 스페이스로 변환 +set expandtab + +" 들여쓰기와 정렬에 자동 탭 및 스페이스 사용 +set smarttab +``` + +### 참고 자료 + +[(영어) Vim 홈페이지](http://www.vim.org/index.php) + +`$ vimtutor` + +[(영어) vim 입문과 기초](https://danielmiessler.com/study/vim/) + +[(영어) 엄마가 말해주지 않은 Vim의 어두운 구석들 (Stack Overflow 게시물)](http://stackoverflow.com/questions/726894/what-are-the-dark-corners-of-vim-your-mom-never-told-you-about) + +[(영어) 아치 리눅스 위키](https://wiki.archlinux.org/index.php/Vim) diff --git a/less.html.markdown b/less.html.markdown index ee67c1bc..1b26eb99 100644 --- a/less.html.markdown +++ b/less.html.markdown @@ -6,7 +6,7 @@ contributors: --- Less is a CSS pre-processor, that adds features such as variables, nesting, mixins and more. -Less (and other preprocessors, such as [Sass](http://sass-lang.com/) help developers to write maintainable and DRY (Don't Repeat Yourself) code. +Less (and other preprocessors, such as [Sass](http://sass-lang.com/)) help developers to write maintainable and DRY (Don't Repeat Yourself) code. ```css diff --git a/logtalk.html.markdown b/logtalk.html.markdown index 385e38f9..d4010f8b 100644 --- a/logtalk.html.markdown +++ b/logtalk.html.markdown @@ -29,7 +29,7 @@ Logtalk provides _objects_, _protocols_, and _categories_ as first-class entitie An object encapsulates predicate declarations and definitions. Objects can be created dynamically but are usually static and defined in source files. A single source file can contain any number of entity definitions. A simple object, defining a list member public predicate: -``` +```logtalk :- object(list). :- public(member/2). @@ -44,7 +44,7 @@ An object encapsulates predicate declarations and definitions. Objects can be cr Assuming that the code above for the `list` object is saved in a `list.lgt` file, it can be compiled and loaded using the `logtalk_load/1` built-in predicate or its abbreviation, `{}/1`, with the file path as argument (the extension can be omitted): -``` +```logtalk ?- {list}. yes ``` @@ -53,7 +53,7 @@ yes The `::/2` infix operator is used to send a message to an object. As in Prolog, we can backtrack for alternative solutions: -``` +```logtalk ?- list::member(X, [1,2,3]). X = 1 ; X = 2 ; @@ -63,7 +63,7 @@ yes Encapsulation is enforced. A predicate can be declared _public_, _protected_, or _private_. It can also be _local_ when there is no scope directive for it. For example: -``` +```logtalk :- object(scopes). :- private(bar/0). @@ -76,7 +76,7 @@ Encapsulation is enforced. A predicate can be declared _public_, _protected_, or Assuming the object is saved in a `scopes.lgt` file: -``` +```logtalk ?- {scopes}. yes @@ -97,7 +97,7 @@ yes When the predicate in a message is unknown for the object (the role it plays determines the lookup procedures), we also get an error. For example: -``` +```logtalk ?- catch(scopes::unknown, Error, true). Error = error( existence_error(predicate_declaration, unknown/0), @@ -112,7 +112,7 @@ A subtle point is that predicate scope directives specify predicate _calling_ se Protocols contain predicate declarations that can be implemented by any number of objects and categories: -``` +```logtalk :- protocol(listp). :- public(member/2). @@ -131,7 +131,7 @@ Protocols contain predicate declarations that can be implemented by any number o The scope of the protocol predicates can be restricted using protected or private implementation. For example: -``` +```logtalk :- object(stack, implements(private::listp)). @@ -144,7 +144,7 @@ In fact, all entity relations (in an entity opening directive) can be qualified An object without an _instantiation_ or _specialization_ relation with another object plays the role of a prototype. A prototype can _extend_ another object, its parent prototype. -``` +```logtalk % clyde, our prototypical elephant :- object(clyde). @@ -167,7 +167,7 @@ An object without an _instantiation_ or _specialization_ relation with another o When answering a message sent to an object playing the role of a prototype, we validate the message and look for an answer first in the prototype itself and, if not found, we delegate to the prototype parents if any: -``` +```logtalk ?- fred::number_of_legs(N). N = 4 yes @@ -179,7 +179,7 @@ yes A message is valid if the corresponding predicate is declared (and the sender is within scope) but it will fail, rather then throwing an error, if the predicate is not defined. This is called the _closed-world assumption_. For example, consider the following object, saved in a `foo.lgt` file: -``` +```logtalk :- object(foo). :- public(bar). @@ -189,7 +189,7 @@ A message is valid if the corresponding predicate is declared (and the sender is Loading the file and trying to call the `bar/0` predicate fails as expected. Note that this is different from calling an _unknown_ predicate, which results in an error: -``` +```logtalk ?- {foo}. yes @@ -208,7 +208,7 @@ yes In order to define objects playing the role of classes and/or instances, an object must have at least an instantiation or a specialization relation with another object. Objects playing the role of meta-classes can be used when we need to see a class also as an instance. We use the following example to also illustrate how to dynamically create new objects at runtime: -``` +```logtalk % a simple, generic, metaclass defining a new/2 predicate for its instances :- object(metaclass, instantiates(metaclass)). @@ -245,7 +245,7 @@ In order to define objects playing the role of classes and/or instances, an obje When answering a message sent to an object playing the role of an instance, we validate the message by starting in its class and going up to its class superclasses if necessary. Assuming that the message is valid, then we look for an answer starting in the instance itself: -``` +```logtalk ?- person::new(Instance, [name(paulo)]). Instance = o1 yes @@ -267,7 +267,7 @@ yes A category is a fine grained unit of code reuse, used to encapsulate a _cohesive_ set of predicate declarations and definitions, implementing a _single_ functionality, that can be imported into any object. A category can thus be seen as the dual concept of a protocol. In the following example, we define categories representing car engines and then import them into car objects: -``` +```logtalk % a protocol describing engine characteristics :- protocol(carenginep). @@ -321,7 +321,7 @@ A category is a fine grained unit of code reuse, used to encapsulate a _cohesive Categories are independently compiled and thus allow importing objects to be updated by simple updating the imported categories without requiring object recompilation. Categories also provide _runtime transparency_. I.e. the category protocol adds to the protocol of the objects importing the category: -``` +```logtalk ?- sedan::current_predicate(Predicate). Predicate = reference/1 ; Predicate = capacity/1 ; @@ -336,7 +336,7 @@ yes Categories can be also be used for hot-patching objects. A category can add new predicates to an object and/or replace object predicate definitions. For example, consider the following object: -``` +```logtalk :- object(buggy). :- public(p/0). @@ -347,7 +347,7 @@ Categories can be also be used for hot-patching objects. A category can add new Assume that the object prints the wrong string when sent the message `p/0`: -``` +```logtalk ?- {buggy}. yes @@ -358,7 +358,7 @@ yes If the object source code is not available and we need to fix an application running the object code, we can simply define a category that fixes the buggy predicate: -``` +```logtalk :- category(patch, complements(buggy)). @@ -370,7 +370,7 @@ If the object source code is not available and we need to fix an application run After compiling and loading the category into the running application we will now get: -``` +```logtalk ?- {patch}. yes @@ -385,7 +385,7 @@ As hot-patching forcefully breaks encapsulation, there is a `complements` compil Objects and categories can be parameterized by using as identifier a compound term instead of an atom. Object and category parameters are _logical variables_ shared with all encapsulated predicates. An example with geometric circles: -``` +```logtalk :- object(circle(_Radius, _Color)). :- public([ @@ -405,7 +405,7 @@ Objects and categories can be parameterized by using as identifier a compound te Parametric objects are used just as any other object, usually providing values for the parameters when sending a message: -``` +```logtalk ?- circle(1.23, blue)::area(Area). Area = 4.75291 yes @@ -413,7 +413,7 @@ yes Parametric objects also provide a simple way of associating a set of predicates with a plain Prolog predicate. Prolog facts can be interpreted as _parametric object proxies_ when they have the same functor and arity as the identifiers of parametric objects. Handy syntax is provided to for working with proxies. For example, assuming the following clauses for a `circle/2` predicate: -``` +```logtalk circle(1.23, blue). circle(3.71, yellow). circle(0.39, green). @@ -423,7 +423,7 @@ circle(8.32, cyan). With these clauses loaded, we can easily compute for example a list with the areas of all the circles: -``` +```logtalk ?- findall(Area, {circle(_, _)}::area(Area), Areas). Areas = [4.75291, 43.2412, 0.477836, 103.508, 217.468] yes @@ -435,7 +435,7 @@ The `{Goal}::Message` construct proves `Goal`, possibly instantiating any variab Logtalk supports _event-driven programming_ by allowing defining events and monitors for those events. An event is simply the sending of a message to an object. Interpreting message sending as an atomic activity, a _before_ event and an _after_ event are recognized. Event monitors define event handler predicates, `before/3` and `after/3`, and can query, register, and delete a system-wide event registry that associates events with monitors. For example, a simple tracer for any message being sent using the `::/2` control construct can be defined as: -``` +```logtalk :- object(tracer, implements(monitoring)). % built-in protocol for event handlers @@ -454,7 +454,7 @@ Logtalk supports _event-driven programming_ by allowing defining events and moni Assuming that the `tracer` object and the `list` object defined earlier are compiled and loaded, we can observe the event handlers in action by sending a message: -``` +```logtalk ?- list::member(X, [1,2,3]). call: list <-- member(X, [1,2,3]) from user @@ -475,7 +475,7 @@ Event-driven programming can be seen as a form of _computational reflection_. Bu Logtalk supports lambda expressions. Lambda parameters are represented using a list with the `(>>)/2` infix operator connecting them to the lambda. Some simple examples using library meta-predicates: -``` +```logtalk ?- {library(metapredicates_loader)}. yes @@ -486,7 +486,7 @@ yes Currying is also supported: -``` +```logtalk ?- meta::map([X]>>([Y]>>(Y is 2*X)), [1,2,3], Ys). Ys = [2,4,6] yes @@ -498,7 +498,7 @@ Lambda free variables can be expressed using the extended syntax `{Free1, ...}/[ Terms and goals in source files can be _expanded_ at compile time by specifying a _hook object_ that defines term-expansion and goal-expansion rules. For example, consider the following simple object, saved in a `source.lgt` file: -``` +```logtalk :- object(source). :- public(bar/1). @@ -511,7 +511,7 @@ Terms and goals in source files can be _expanded_ at compile time by specifying Assume the following hook object, saved in a `my_macros.lgt` file, that expands clauses and calls to the `foo/1` local predicate: -``` +```logtalk :- object(my_macros, implements(expanding)). % built-in protocol for expanding predicates @@ -525,7 +525,7 @@ Assume the following hook object, saved in a `my_macros.lgt` file, that expands After loading the macros file, we can then expand our source file with it using the `hook` compiler flag: -``` +```logtalk ?- logtalk_load(my_macros), logtalk_load(source, [hook(my_macros)]). yes diff --git a/no-nb/bash-no.html.markdown b/no-nb/bash-no.html.markdown index ab0c064f..481aecbd 100644 --- a/no-nb/bash-no.html.markdown +++ b/no-nb/bash-no.html.markdown @@ -217,8 +217,6 @@ bar () # Å kalle en funksjon: foo "Mitt navn er" $NAME -# There are a lot of useful commands you should learn: -# prints last 10 lines of file.txt # Det er mange nyttige kommandoer du bør lære deg: # "tail" skriver ut slutten av en fil, i dette tilfellet de siste 10 linjene tail -n 10 file.txt diff --git a/perl.html.markdown b/perl.html.markdown index 3cbd2801..a29fdf1f 100644 --- a/perl.html.markdown +++ b/perl.html.markdown @@ -51,6 +51,13 @@ my @mixed = ("camel", 42, 1.23); # indicate one value will be returned. my $second = $animals[1]; +# The size of an array is retrieved by accessing the array in a scalar +# context, such as assigning it to a scalar variable or using the +# "scalar" operator. + +my $num_animals = @animals; +print "Number of numbers: ", scalar(@numbers), "\n"; + ## Hashes # A hash represents a set of key/value pairs: @@ -67,6 +74,11 @@ my %fruit_color = ( # Hash elements are accessed using curly braces, again with the $ sigil. my $color = $fruit_color{apple}; +# All of the keys or values that exist in a hash can be accessed using +# the "keys" and "values" functions. +my @fruits = keys %fruit_color; +my @colors = values %fruit_color; + # Scalars, arrays and hashes are documented more fully in perldata. # (perldoc perldata). @@ -144,6 +156,12 @@ for (@elements) { print; } +# iterating through a hash (for and foreach are equivalent) + +foreach my $key (keys %hash) { + print $key, ': ', $hash{$key}, "\n"; +} + # the Perlish post-condition way again print for @elements; @@ -170,8 +188,11 @@ $x =~ s/foo/bar/g; # replaces ALL INSTANCES of foo with bar in $x # You can open a file for input or output using the "open()" function. +# For reading: open(my $in, "<", "input.txt") or die "Can't open input.txt: $!"; +# For writing (clears file if it exists): open(my $out, ">", "output.txt") or die "Can't open output.txt: $!"; +# For writing (appends to end of file): open(my $log, ">>", "my.log") or die "Can't open my.log: $!"; # You can read from an open filehandle using the "<>" operator. In @@ -182,6 +203,12 @@ open(my $log, ">>", "my.log") or die "Can't open my.log: $!"; my $line = <$in>; my @lines = <$in>; +# You can write to an open filehandle using the standard "print" +# function. + +print $out @lines; +print $log $msg, "\n"; + #### Writing subroutines # Writing subroutines is easy: diff --git a/perl6.html.markdown b/perl6.html.markdown index 34ad70b7..defd1315 100644 --- a/perl6.html.markdown +++ b/perl6.html.markdown @@ -18,7 +18,7 @@ double paragraphs, and single notes. `#=>` represents the output of a command. -```perl +```perl6 # Single line comment start with a pound #`( @@ -813,7 +813,7 @@ die X::AdHoc.new(payload => 'Error!'); # Undefined values include: `Nil`, `Mu` and `Failure` as well as `Int`, `Str` # and other types that have not been initialized to any value yet. # You can check if something is defined or not using the defined method: -my $uninitialized; +my $uninitialized; say $uninitiazilzed.defined; #> False # When using `orelse` it will disarm the exception and alias $_ to that failure # This will avoid it being automatically handled and printing lots of scary @@ -1092,7 +1092,7 @@ say (1, 10, (20, 10) ).flat; #> (1 10 20 10) Now the iterable is flat # - `lazy` - Defer actual evaluation until value is fetched (forces lazy context) my @lazy-array = (1..100).lazy; -say @lazy-array.is-lazy; #> True # Check for lazyness with the `is-lazy` method. +say @lazy-array.is-lazy; #> True # Check for lazyness with the `is-lazy` method. say @lazy-array; #> [...] List has not been iterated on! my @lazy-array { .print }; # This works and will only do as much work as is # needed. diff --git a/php.html.markdown b/php.html.markdown index 82d27546..ddf38226 100644 --- a/php.html.markdown +++ b/php.html.markdown @@ -467,7 +467,7 @@ function variable($word, ...$list) { } } -variable("Separate", "Hello", "World") // Separate || Hello | World | +variable("Separate", "Hello", "World"); // Separate || Hello | World | /******************************** * Includes @@ -824,7 +824,7 @@ echo "Current method is " . __METHOD__; echo "Current namespace is " . __NAMESPACE__; // Get the name of the current trait. Only returns a value when used inside a trait or object declaration. -echo "Current namespace is " . __TRAIT__; +echo "Current trait is " . __TRAIT__; /********************** * Error Handling diff --git a/pl-pl/haskell-pl.html.markdown b/pl-pl/haskell-pl.html.markdown new file mode 100644 index 00000000..5eb68e2e --- /dev/null +++ b/pl-pl/haskell-pl.html.markdown @@ -0,0 +1,444 @@ +--- +language: Haskell +lang: pl-pl +contributors: + - ["Remigiusz Suwalski", "https://github.com/remigiusz-suwalski"] +--- + +Haskell został zaprojektowany jako praktyczny, czysto funkcyjny język +programowania. Jest znany przede wszystkim ze względu na jego monady oraz system +typów, ale ja lubię do niego wracać przez jego elegancję. Sprawił on, że +programowanie jest prawdziwą przyjemnością. + +```haskell +-- Komentarze jednolinijkowe zaczynają się od dwóch myślników +{- Komentarze wielolinijkowe należy +zamykać w bloki klamrami. +-} + +---------------------------------------------------- +-- 1. Podstawowe typy danych oraz operatory +---------------------------------------------------- + +-- Mamy liczby +3 -- 3 + +-- Podstawowe działania działają tak, jak powinny +1 + 1 -- 2 +8 - 1 -- 7 +10 * 2 -- 20 +35 / 5 -- 7.0 + +-- dzielenie domyślnie zwraca ,,dokładny'' wynik +35 / 4 -- 8.75 + +-- dzielenie całkowitoliczbowe +35 `div` 4 -- 8 + +-- wartości logiczne także są podstawowym typem danych: +True +False + +-- operacje logiczne: negacja oraz porównania +not True -- False +not False -- True +1 == 1 -- True +1 /= 1 -- False +1 < 10 -- True + +-- W powyższych przykładach, `not` jest funkcją przyjmującą jeden argument. +-- Haskell nie potrzebuje nawiasów, by wywołać funkcję: argumenty są po prostu +-- wypisywane jeden za drugim. Ogólnie wygląda to tak: +-- funkcja arg1 arg2 arg3... +-- Sekcja poświęcona funkcjom zawiera informacje, jak stworzyć własne. + +-- Łańcuchy znaków (stringi) i pojedyncze znaki: +"To jest lancuch." +'a' -- znak +'Nie mozna laczyc apostrofow z lancuchami.' -- błąd! + +-- Łańcuchy można sklejać +"Hello " ++ "world!" -- "Hello world!" + +-- Łańcuch jest listą własnych znaków +['H', 'e', 'l', 'l', 'o'] -- "Hello" +"To jest lancuch" !! 0 -- 'T' + +---------------------------------------------------- +-- Listy oraz krotki +---------------------------------------------------- + +-- Wszystkie elementy listy muszą być tego samego typu. +-- Poniższe dwie listy są identyczne: +[1, 2, 3, 4, 5] +[1..5] + +-- Zakresy są uniwersalne. +['A'..'F'] -- "ABCDEF" + +-- Przy tworzeniu zakresów można określić krok. +[0,2..10] -- [0, 2, 4, 6, 8, 10] +[5..1] -- To nie zadziała, gdyż w Haskellu zakresy tworzone są domyślnie rosnąco +[5,4..1] -- [5, 4, 3, 2, 1] + +-- indeksowanie listy od zera +[1..10] !! 3 -- 4 + +-- Można nawet tworzyć listy nieskończone! +[1..] -- lista wszystkich liczb naturalnych + +-- Nieskończone listy mają prawo działać, ponieważ Haskell cechuje się leniwym +-- wartościowaniem. To oznacza, że obliczane są jedynie te elementy listy, +-- których istotnie potrzebujemy. Możemy poprosić o tysiączny element i +-- dostaniemy go: + +[1..] !! 999 -- 1000 + +-- Haskell wyznaczył pierwsze tysiąc elementów listy, ale cała jej reszta +-- jeszcze nie istnieje! Nie zostanie obliczona ich wartość, póki nie zajdzie +-- taka potrzeba. + +-- łączenie dwóch list +[1..5] ++ [6..10] + +-- dodawanie pojedynczego elementu na początek listy +0:[1..5] -- [0, 1, 2, 3, 4, 5] + +-- więcej operacji na listach +head [1..5] -- 1 +tail [1..5] -- [2, 3, 4, 5] +init [1..5] -- [1, 2, 3, 4] +last [1..5] -- 5 + +-- list comprehensions +[x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10] + +-- z dodatkowym warunkiem +[x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10] + +-- każdy element krotki może być innego typu, jednak sama krotka musi być stałej +-- długości. Przykładowo: +("haskell", 1) + +-- dostęp do elementów pary (krotki długości 2): +fst ("haskell", 1) -- "haskell" +snd ("haskell", 1) -- 1 + +---------------------------------------------------- +-- 3. Funkcje +---------------------------------------------------- +-- Prosta funkcja przyjmująca dwa argumenty +add a b = a + b + +-- Pamiętaj, że podczas stosowania ghci, interpretera Haskella, wszelkie +-- definicje muszą zostać poprzedzone słowem `let`, na przykład: +-- let add a b = a + b + +-- Używanie funkcji: +add 1 2 -- 3 + +-- Nazwę funkcji można podać między dwoma argumentami, ale wtedy musi zostać +-- otoczona grawisami: +1 `add` 2 -- 3 + +-- Nazwa funkcji nie musi zawierać żadnych liter, przykładem czego jest +-- operator dzielenia: +(//) a b = a `div` b +35 // 4 -- 8 + +-- Strażnicy: prosty sposób na rozbijanie funkcji na przypadki +fib x + | x < 2 = 1 + | otherwise = fib (x - 1) + fib (x - 2) + +-- Dopasowanie wzorca jest podobne. Haskell sam automatycznie wybierze, która +-- z poniższych definicji fib powinna zostać użyta: +fib 1 = 1 +fib 2 = 2 +fib x = fib (x - 1) + fib (x - 2) + +-- Dopasowanie z krotkami: +foo (x, y) = (x + 1, y + 2) + +-- Dopasowanie z listami. Tutaj `x` jest pierwszym elementem listy, +-- natomiast `xs` to jej reszta (ogon). Poniższa funkcja nakłada funkcję +-- na każdy z elementów listy: +myMap func [] = [] +myMap func (x:xs) = func x:(myMap func xs) + +-- Funkcje anonimowe tworzone są przy użyciu w-tył-ciachu, po którym następują +-- wszystkie argumenty: +myMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7] + +-- używanie zwijania z anonimowymi funkcjami: foldl1 zwija z lewej strony, +-- przyjmując jako wartość początkową zbieracza pierwszy element listy. +foldl1 (\acc x -> acc + x) [1..5] -- 15 + +---------------------------------------------------- +-- 4. Więcej funkcji +---------------------------------------------------- + +-- częściowe nakładanie: jeśli funkcja nie otrzyma wszystkich swoich argumentów, +-- zostaje cześciowo nałożona - zwraca funkcję, która przyjmuje pozostałe, +-- brakujące argumenty. + +add a b = a + b +foo = add 10 -- foo jest teraz funkcją, która przyjmuje liczbę, zwiększa ją o 10 +foo 5 -- 15 + +-- Inny sposób na zapisanie tego samego: +foo = (10+) +foo 5 -- 15 + +-- składanie funkcji: +-- operator `.` składa wiele funkcji w jedną. +-- Dla przykładu, foo jest funkcją, która powiększa swój argument o 10, mnoży +-- tak uzyskaną liczbę przez 4 i zwraca wynik: +foo = (4*) . (10+) + +-- 4*(10 + 5) = 60 +foo 5 -- 60 + +-- ustalanie kolejności +-- Haskell posiada inny operator, `$`, który nakłada funkcję do podanego +-- parametru. W przeciwieństwie do zwykłego lewostronnie łącznego nakładania +-- funkcji, którego priorytet jest najwyższy (10), operator `$` posiada +-- priorytet 0 i jest prawostronnie łączny. Tak niski priorytet oznacza, że +-- wyrażenie po prawej traktowane jest jako parametr funkcji po lewej + +-- wcześniej +even (fib 7) -- fałsz + +-- równoważnie +even $ fib 7 -- fałsz + +-- składanie funkcji +even . fib $ 7 -- fałsz + + +---------------------------------------------------- +-- 5. Sygnatury typów +---------------------------------------------------- + +-- Haskell posiada wyjątkowo silny system typów, w którym każde poprawne +-- wyrażenie ma swój typ. + +-- Kilka podstawowych typów: +5 :: Integer +"hello" :: String +True :: Bool + +-- Funkcje też są określonego typu. +-- `not` przyjmuje wartość logiczną i taką też zwraca: +-- not :: Bool -> Bool + +-- Przykład funkcji przyjmującej dwa argumenty +-- add :: Integer -> Integer -> Integer + +-- Dobrą praktyką podczas definiowania wartości jest napisanie nad nią +-- także jej typu: +double :: Integer -> Integer +double x = x * 2 + +---------------------------------------------------- +-- 6. Wyrażenia warunkowe +---------------------------------------------------- + +-- wyrażenie warunkowe +haskell = if 1 == 1 then "wspaniale" else "paskudnie" -- haskell = "wspaniale" + +-- wyrażenie warunkowe można rozbić na wiele linii, +-- ale trzeba uważać na wcięcia w kodzie +haskell = if 1 == 1 + then "wspaniale" + else "paskudnie" + +-- rozpatrywanie przypadków: oto jak można parsować argumenty z linii poleceń: +case args of + "help" -> printHelp + "start" -> startProgram + _ -> putStrLn "bad args" + +-- Haskell zastępuje pętle (których nie ma) rekurencyjnymi wywołaniami funkcji. +-- map aplikuje funkcję do każdego elementu listy: + +map (*2) [1..5] -- [2, 4, 6, 8, 10] + +-- możesz zdefiniować funkcję for przy użyciu map: +for array func = map func array + +-- a następnie użyć jej: +for [0..5] $ \i -> show i + +-- mogliśmy użyć krótszego zapisu bez zmiany działania funkcji for: +for [0..5] show + +-- Do redukcji listy służy polecenie foldl (foldr): +-- foldl <fn> <initial value> <list> +foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43 + +-- Jest to równoważne z: +(2 * (2 * (2 * 4 + 1) + 2) + 3) + +-- foldl składa od od lewej strony, foldr od prawej +foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16 + +-- To zaś równoważne jest: +(2 * 1 + (2 * 2 + (2 * 3 + 4))) + +---------------------------------------------------- +-- 7. Typy danych +---------------------------------------------------- + +-- Oto jak tworzy się nowe typy danych w Haskellu: + +data Color = Red | Blue | Green + +-- Teraz można używać ich we własnych funkcjach: + +say :: Color -> String +say Red = "You are Red!" +say Blue = "You are Blue!" +say Green = "You are Green!" + +-- Twoje typy danych mogą posiadać nawet parametry: + +data Maybe a = Nothing | Just a + +-- Wszystkie poniższe są typu Maybe +Just "hello" -- typu `Maybe String` +Just 1 -- typu `Maybe Int` +Nothing -- typu `Maybe a` for any `a` + +---------------------------------------------------- +-- 8. Haskell IO +---------------------------------------------------- + +-- Chociaż obsługa wejścia i wyjścia nie może zostać wyjaśniona przez poznaniem +-- monad, spróbujemy zrobić to częściowo + +-- Wykonanie programu napisanego w Haskellu wywołuje funkcję `main` +-- Musi zwrócić wartość typu `IO a` dla pewnego `a`. Przykład: + +main :: IO () +main = putStrLn $ "Hello, sky! " ++ (say Blue) +-- putStrLn has type String -> IO () + +-- Najłatwiej obsłużyć wejście i wyjście, kiedy program zostanie +-- zaimplementowany jako funkcja String -> String. Funkcja +-- interact :: (String -> String) -> IO () +-- pobiera pewien tekst, wykonuje na nim operacje, po czym wypisuje wynik. + +countLines :: String -> String +countLines = show . length . lines + +main' = interact countLines + +-- Możesz myśleć o wartości typu `IO ()` jako reprezentującej ciąg czynności, +-- które komputer ma wykonać, zupełnie niczym program komputerowy w imperatywnym +-- języku programowania. Akcje można łączyć przy użyciu notacji `do`: + +sayHello :: IO () +sayHello = do + putStrLn "What is your name?" + name <- getLine -- this gets a line and gives it the name "name" + putStrLn $ "Hello, " ++ name + +-- Ćwiczenie: napisz własną wersję `interact`, +-- która czyta tylko jedną linię wejścia. + +-- Kod w `sayHello` nigdy się nie wykona. Jedyną akcją, która zostanie +-- uruchomiona, jest wartość `main`. +-- Aby uruchomić `sayHello`, należy zastąpić poprzednią definicję `main` przez +-- main = sayHello + +-- Spróbujmy lepiej zrozumieć, jak działa funkcja `getLine`, której właśnie +-- użyliśmy. Jej typem jest +-- getLine :: IO String +-- Możesz myśleć o wartości typu `IO a` jako reprezentującej program, który +-- wygeneruje wartość typu `a`, poza wszystkim innym, co jeszcze zrobi. +-- Możemy także tworzyć własne akcje typu `IO String`: + +action :: IO String +action = do + putStrLn "This is a line. Duh" + input1 <- getLine + input2 <- getLine + -- The type of the `do` statement is that of its last line. + -- `return` is not a keyword, but merely a function + return (input1 ++ "\n" ++ input2) -- return :: String -> IO String + +-- Możemy użyć tego tak jak używaliśmy `getLine`: + +main'' = do + putStrLn "I will echo two lines!" + result <- action + putStrLn result + putStrLn "This was all, folks!" + +-- Typ `IO` jest przykładem monady. Sposób w jakim Haskell używa monad do +-- obsługi wejścia i wyjścia pozwala mu być czysto funkcyjnym językiem. +-- Każda funkcja, która wchodzi w interakcje ze światem zewnętrznym, oznaczana +-- jest jako `IO` w jej sygnaturze typu, co umożliwia odróżnianie funkcji +-- czystych od zależnych od świata lub modyfikujących stan. + +-- To naprawdę użyteczna własność, dzięki której jesteśmy w stanie uruchamiać +-- czyste funkcje jednocześnie. + +---------------------------------------------------- +-- 9. Interaktywne środowisko programowania +---------------------------------------------------- + +-- Aby uruchomić repl (read-eval-print loop, interaktywne środowisko), należy +-- wpisać `ghci`. Można już programować. Do definiowania nowych wartości służy +-- słowo kluczowe `let`: + +let foo = 5 + +-- Do sprawdzania typów dowolnej wartości (wyrażenia) wykorzystuje się `:t`: + +> :t foo +foo :: Integer + +-- Działania takie jak `+`, `:` czy `$`, są funkcjami. +-- Przed sprawdzeniem ich typu należy otoczyć je nawiasami: + +> :t (:) +(:) :: a -> [a] -> [a] + +-- Dodatkowych informacji dostarcza `:i`: + +> :i (+) +class Num a where + (+) :: a -> a -> a + ... + -- Defined in ‘GHC.Num’ +infixl 6 + + +-- Można nawet wykonywać akcje typu `IO ()`! + +> sayHello +What is your name? +Friend! +Hello, Friend! + +``` + +Pominęliśmy wiele aspektów Haskella, wliczając w to monady. To właśnie one +sprawiają, że programowanie w Haskellu sprawia tyle frajdy. Na zakończenie +pokażę Tobie implementację algorytmu quicksort w Haskellu: + +```haskell +qsort [] = [] +qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater + where lesser = filter (< p) xs + greater = filter (>= p) xs +``` + +Haskell może zostać zainstalowany na co najmniej dwa sposoby: + - tradycyjnie [przy użyciu Cabala](http://www.haskell.org/platform/), + - nowocześnie [z pomocą Stack](https://www.stackage.org/install). + +Godnymi poleceniami wprowadzeniami są wspaniałe +[Learn you a Haskell](http://learnyouahaskell.com/) albo +[Real World Haskell](http://book.realworldhaskell.org/). diff --git a/powershell.html.markdown b/powershell.html.markdown index f34d5b4e..bd46051c 100644 --- a/powershell.html.markdown +++ b/powershell.html.markdown @@ -35,7 +35,7 @@ $PSVersionTable Getting help: -``` +```powershell # Find commands Get-Command about_* # alias: gcm Get-Command -Verb Add @@ -52,7 +52,7 @@ Update-Help # Run as admin The tutorial starts here: -``` +```powershell # As you already figured, comments start with # # Simple hello world example: @@ -74,7 +74,7 @@ $aHashtable = @{name1='val1'; name2='val2'} # Using variables: echo $aString echo "Interpolation: $aString" -echo "`$aString has length of $($aString.Length)" +echo "$aString has length of $($aString.Length)" echo '$aString' echo @" This is a Here-String @@ -300,7 +300,7 @@ $Shortcut.Save() Configuring your shell -``` +```powershell # $Profile is the full path for your `Microsoft.PowerShell_profile.ps1` # All code there will be executed when the PS session starts if (-not (Test-Path $Profile)) { diff --git a/pt-br/c++-pt.html.markdown b/pt-br/c++-pt.html.markdown index e2e95268..fd392b9e 100644 --- a/pt-br/c++-pt.html.markdown +++ b/pt-br/c++-pt.html.markdown @@ -19,9 +19,9 @@ foi concebida para - suportar programação genérica Embora sua sintaxe pode ser mais difícil ou complexa do que as linguagens mais -recentes, C++ é amplamente utilizado porque compila para instruções nativas que -podem ser executadas diretamente pelo processador e oferece um controlo rígido sobre hardware (como C), enquanto oferece recursos de alto nível, como os -genéricos, exceções e classes. Esta combinação de velocidade e funcionalidade +recentes, C++ é amplamente utilizado porque compila para instruções nativas que +podem ser executadas diretamente pelo processador e oferece um controlo rígido sobre hardware (como C), enquanto oferece recursos de alto nível, como os +genéricos, exceções e classes. Esta combinação de velocidade e funcionalidade faz C++ uma das linguagens de programação mais utilizadas. ```c++ @@ -33,7 +33,7 @@ faz C++ uma das linguagens de programação mais utilizadas. // declarações de variáveis, tipos primitivos, e funções. No entanto, C++ varia // em algumas das seguintes maneiras: -// A função main() em C++ deve retornar um int, embora void main() é aceita +// A função main() em C++ deve retornar um int, embora void main() é aceita // pela maioria dos compiladores (gcc, bumbum, etc.) // Este valor serve como o status de saída do programa. // Veja http://en.wikipedia.org/wiki/Exit_status para mais informações. @@ -105,7 +105,7 @@ int main() // Parâmetros padrão de função ///////////////////////////// -// Você pode fornecer argumentos padrões para uma função se eles não são +// Você pode fornecer argumentos padrões para uma função se eles não são // fornecidos pelo chamador. void doSomethingWithInts(int a = 1, int b = 4) @@ -157,7 +157,7 @@ void foo() int main() { - // Assuma que tudo é do namespace "Second" a menos que especificado de + // Assuma que tudo é do namespace "Second" a menos que especificado de // outra forma. using namespace Second; @@ -222,7 +222,7 @@ cout << myString; // "Hello Dog" // Além de indicadores como os de C, C++ têm _referências_. Esses são tipos de // ponteiro que não pode ser reatribuída uma vez definidos e não pode ser nulo. -// Eles também têm a mesma sintaxe que a própria variável: Não * é necessário +// Eles também têm a mesma sintaxe que a própria variável: Não * é necessário // para _dereferencing_ e & (endereço de) não é usado para atribuição. using namespace std; @@ -258,7 +258,7 @@ class Dog { std::string name; int weight; -// Todos os membros a seguir este são públicos até que "private:" ou +// Todos os membros a seguir este são públicos até que "private:" ou // "protected:" é encontrado. public: @@ -274,13 +274,13 @@ public: void setWeight(int dogsWeight); - // Funções que não modificam o estado do objecto devem ser marcadas como + // Funções que não modificam o estado do objecto devem ser marcadas como // const. Isso permite que você chamá-los se for dada uma referência const // para o objeto. Além disso, observe as funções devem ser explicitamente - // declarados como _virtual_, a fim de ser substituídas em classes - // derivadas. As funções não são virtuais por padrão por razões de + // declarados como _virtual_, a fim de ser substituídas em classes + // derivadas. As funções não são virtuais por padrão por razões de // performance. - + virtual void print() const; // As funções também podem ser definidas no interior do corpo da classe. @@ -291,7 +291,7 @@ public: // Estes são chamados quando um objeto é excluído ou fica fora do escopo. // Isto permite paradigmas poderosos, como RAII // (veja abaixo) - // Destruidores devem ser virtual para permitir que as classes de ser + // Destruidores devem ser virtual para permitir que as classes de ser // derivada desta. virtual ~Dog(); @@ -323,7 +323,7 @@ void Dog::print() const void Dog::~Dog() { - cout << "Goodbye " << name << "\n"; + std::cout << "Goodbye " << name << "\n"; } int main() { @@ -343,8 +343,8 @@ class OwnedDog : public Dog { // Substituir o comportamento da função de impressão de todas OwnedDogs. // Ver http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping - // Para uma introdução mais geral, se você não estiver familiarizado com o - // polimorfismo subtipo. A palavra-chave override é opcional, mas torna-se + // Para uma introdução mais geral, se você não estiver familiarizado com o + // polimorfismo subtipo. A palavra-chave override é opcional, mas torna-se // na verdade você está substituindo o método em uma classe base. void print() const override; @@ -371,8 +371,8 @@ void OwnedDog::print() const // Inicialização e Sobrecarga de Operadores ////////////////////////////////////////// -// Em C ++, você pode sobrecarregar o comportamento dos operadores, tais como -// +, -, *, /, etc. Isto é feito através da definição de uma função que é +// Em C ++, você pode sobrecarregar o comportamento dos operadores, tais como +// +, -, *, /, etc. Isto é feito através da definição de uma função que é // chamado sempre que o operador é usado. #include <iostream> @@ -438,7 +438,7 @@ int main () { // mas qualquer tipo pode ser jogado como uma exceção #include <exception> -// Todas as exceções lançadas dentro do bloco try pode ser capturado por +// Todas as exceções lançadas dentro do bloco try pode ser capturado por // manipuladores de captura subseqüentes try { // Não aloca exceções no heap usando _new_. @@ -460,7 +460,7 @@ catch (const std::exception& ex) /////// // RAII significa alocação de recursos é de inicialização. -// Muitas vezes, é considerado o paradigma mais poderoso em C++, e é o +// Muitas vezes, é considerado o paradigma mais poderoso em C++, e é o // conceito simples que um construtor para um objeto adquire recursos daquele // objeto e o destruidor liberá-los. @@ -479,11 +479,11 @@ void doSomethingWithAFile(const char* filename) } // Infelizmente, as coisas são levemente complicadas para tratamento de erros. -// Suponha que fopen pode falhar, e que doSomethingWithTheFile e -// doSomethingElseWithIt retornam códigos de erro se eles falharem. (As -// exceções são a forma preferida de lidar com o fracasso, mas alguns -// programadores, especialmente aqueles com um conhecimento em C, discordam -// sobre a utilidade de exceções). Agora temos que verificar cada chamada para +// Suponha que fopen pode falhar, e que doSomethingWithTheFile e +// doSomethingElseWithIt retornam códigos de erro se eles falharem. (As +// exceções são a forma preferida de lidar com o fracasso, mas alguns +// programadores, especialmente aqueles com um conhecimento em C, discordam +// sobre a utilidade de exceções). Agora temos que verificar cada chamada para // o fracasso e fechar o identificador de arquivo se ocorreu um problema. bool doSomethingWithAFile(const char* filename) @@ -609,7 +609,7 @@ h=sum<double>(f,g); ``` Leitura Adicional: -Uma referência atualizada da linguagem pode ser encontrada em +Uma referência atualizada da linguagem pode ser encontrada em <http://cppreference.com/w/cpp> Uma fonte adicional pode ser encontrada em <http://cplusplus.com> diff --git a/pt-br/scala-pt.html.markdown b/pt-br/scala-pt.html.markdown new file mode 100644 index 00000000..3459f567 --- /dev/null +++ b/pt-br/scala-pt.html.markdown @@ -0,0 +1,668 @@ +--- +language: Scala +filename: learnscala-pt.scala +contributors: + - ["George Petrov", "http://github.com/petrovg"] + - ["Dominic Bou-Samra", "http://dbousamra.github.com"] + - ["Geoff Liu", "http://geoffliu.me"] + - ["Ha-Duong Nguyen", "http://reference-error.org"] +translators: + - ["Francieli Viane", "https://github.com/FFrancieli"] +lang: pt-br +--- + +Scala - a linguagem escalável + +```scala + +///////////////////////////////////////////////// +// 0. O básico +///////////////////////////////////////////////// +/* + Configurando o Scala: + + 1) Baixe o instalador do Scala - http://www.scala-lang.org/downloads + 2) Extraia (unzip ou tar) para sua localização favorita e coloque o subdiretório + bin na variável de ambiente `PATH` +*/ + +/* + Tente o REPL + + Scala tem uma ferramenta chamada REPL (Read-Eval-Print Loop) que é análogo a + interpretadores de linha de comando de outras linguagens. Você pode digitar + qualquer expressão de Scala e o resultado será calculado e impresso. + + O REPL é uma ferramenta muito conveniente para testar e verificar código. Use-o + enquanto você lê o tutorial para explorar os conceitos rapidamente por conta própria. +*/ + +//Inicialize um REPL de Scala executando o comando scala no terminal. Você deve ver o prompt: +$ scala +scala> + +//Por padrão, cada expressão que você executa é salva como um novo valor enumerado: +scala> 2 + 2 +res0: Int = 4 + +// Valores padrões podem ser reutilizados. Observe o tipo do valor exibido no resultado... +scala> res0 + 2 +res1: Int = 6 + +// Scala é uma linguagem fortemente tipada. Você pode usar o REPL para verfificar o tipo +// sem avaliar uma expressão. + +scala> :type (true, 2.0) +(Boolean, Double) + +// As sessões do REPL podem ser salvas +scala> :save /sites/repl-test.scala + +//Arquivos podem ser carregados no REPL +scala> :load /sites/repl-test.scala +Loading /sites/repl-test.scala... +res2: Int = 4 +res3: Int = 6 + +// Você pode pesquisar em seu histórico recente +scala> :h? +1 2 + 2 +2 res0 + 2 +3 :save /sites/repl-test.scala +4 :load /sites/repl-test.scala +5 :h? + +// Agora que você já sabe brincar, vamos aprender um pouco de Scala... + +///////////////////////////////////////////////// +// 1. Introdução +///////////////////////////////////////////////// + +// Comentários de uma linha começam com duas barras + +/* + Comentários com múltiplas linhas, como você já pode ver, são assim. +*/ + +// Imprimir e forçar uma linha na próxima impressão +println("Hello world!") +println(10) +// Hello world! +// 10 + +//Imprimir sem forçar uma nova linha na próxima impressão +print("Hello world") +print(10) +// Hello world10 + +//A declaração de valores pode ser feita usando tanto o var quanto o val. +// Declarações feitas com `val` são imutáveis, enquanto que declarações feitas +// com var são mutáveis. Imutabilidade é uma coisa boa. +val x = 10 // x is now 10 +x = 20 // error: reassignment to val +var y = 10 + = 20 // y agora é 20 + +/* + Scala é uma linguagem estaticamente tipada. Observe ainda que nas declarações + acima nós não especificamos um tipo. Isso se deve a um recurso da linguagem + chamado de inferência. Na maioria dos casos, o compilador do Scala consegue + adivinhar qual tipo é, de forma que você não precisa digitar sempre. Nós + podemos declarar o tipo da variável de maneira explícita asim: +*/ + +val z: Int = 10 +val a: Double = 1.0 + +// Note que a conversão automática de Int para Double, o resultado é 10.0, não 10 +val b: Double = 10 + +//Valores booleanos +true +false + +//Operações booleanas +!true // false +!false // true +true == false // false +10 > 5 // true + +// Matemática é como o de costume +1 + 1 // 2 +2 - 1 // 1 +5 * 3 // 15 +6 / 2 // 3 +6 / 4 // 1 +6.0 / 4 // 1.5 +6 / 4.0 // 1.5 + +// Calcular uma expressão no REPL te dá o tipo e o valor do resultado +1 + 7 + +/* A linha acima resulta em: + scala> 1 + 7 + res29: Int = 8 + + Isso significa que o resultado ao culcular 1 + 7 é um objeto do tipo Int com + valor 8. + + Note que "res29" é o nome de uma variável gerada sequencialmente para guardar + os resultados das expressões que você executa, logo seu nome pode ser + diferente. +*/ + +"Strings em Scala são delimitadas por aspas duplas" +'a' // Um caractere em Scala +// 'Strings com aspas simples não existem em Scala.' <= isso causa um erro. + +// Strings possuem os métodos comuns de Java definidos +"hello world".length +"hello world".substring(2, 6) +"hello world".replace("C", "3") + +// Elas também possuem alguns métodos extras do Scala. Veja também: +scala.collection.immutable.StringOps +"hello world".take(5) +"hello world".drop(5) + +//Interpolação de string: observe o prefixo "s" +val n = 45 +s"We have $n apples" // => "We have 45 apples" + +// Também é possível ter expressões dentro de interpolação de strings +val a = Array(11, 9, 6) +s"My second daughter is ${a(0) - a(2)} years old." // => "My second daughter is 5 years old." +s"We have double the amount of ${n / 2.0} in apples." // => "We have double the amount of 22.5 in apples." +s"Power of 2: ${math.pow(2, 2)}" // => "Power of 2: 4" + +// Formatação de strings interpoladas com o prefixo "f" +f"Power of 5: ${math.pow(5, 2)}%1.0f" // "Power of 5: 25" +f"Square root of 122: ${math.sqrt(122)}%1.4f" // "Square root of 122: 11.0454" + + +// Strings cruas, ignorando caracteres especiais +raw"New line feed: \n. Carriage return: \r." // => "New line feed: \n. Carriage return: \r." + +//Alguns caracteres precisam ser "escapados", ex. uma aspa dupla dentro de uma string + +"They stood outside the \"Rose and Crown\"" // => "They stood outside the "Rose and Crown"" + +// Aspas triplas permitem strings a abrangerem múltiplas linhas e conter Aspas +val html = """<form id="daform"> + <p>Press belo', Joe</p> + <input type="submit"> + </form>""" + + +///////////////////////////////////////////////// +// 2. Funções +///////////////////////////////////////////////// + +// Funções são definidas da seguinte maneira: +// +// def nomeDaFuncao(args ...): TipoDeRetorno = {body ...} +// +// Se você vem de linguagens mais tradicionais, note a omissão da palavra chave +//return. Em Scala a última expressão no bloco da função é o valor de retorno +def sumOfSquares(x: Int, y: Int): Int = { + val x2 = x * x + val y2 = y * y + x2 + y2 +} + +// As { } podem ser omitidas se o corpo da função possui apenas uma expressão: +def sumOfSquaresShort(x: Int, y: Int): Int = x * x + y * y + +// A sintaxe para chamar funções é familiar: +sumOfSquares(3, 4) // => 25 + +// Você poode usar o nome dos parâmetros para especificá-los numa ordem diferente +def subtract(x: Int, y: Int): Int = x - y + +subtract(10, 3) // => 7 +subtract(y=10, x=3) // => -7 + +// Na maioria dos casos (sendo funções recursivas a a exceção mais notável) o +// tipo de retorno da função pode ser omitido, e o mesmo tipo de inferência que +// vimos nas variáveis funcionará com o valor de retorno da função: +def sq(x: Int) = x * x // O compilador consegue adivinhar que o tipo de retorno é Int + +// Funções podem ter parâmetros padrão: +def addWithDefault(x: Int, y: Int = 5) = x + y +addWithDefault(1, 2) // => 3 +addWithDefault(1) // => 6 + +// Funções anônimas são semelhantes a essa: +(x: Int) => x * x + +// Diferente de defs, até mesmo a entrada de funções anônimas podem ser omitidas +// se o contexto deixar isso claro. Observe o tipo "Int => Int", que significa +// uma função que recebe umn Int e retorna um Int. +val sq: Int => Int = x => x * x + +// Se cada argumento na sua função anônima é usado apenas uma vez, Scala te fornece +// uma maneira ainda mais curta de definí-lo. Estas funções anônimas acabam por +// ser muito comuns, como será mostrado na sessão de estrutura de dados. +val addOne: Int => Int = _ + 1 +val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3) + +addOne(5) // => 6 +weirdSum(2, 4) // => 16 + +// A palavra chave return existe em Scala, mas só retorna do def mais profundo que o cerca. +//AVISO: O uso do return em Scala é propenso a erros e deve ser evitado. +//Não há efeito em funções anônimas. Per exemplo: +def foo(x: Int): Int = { + val anonFunc: Int => Int = { z => + if (z > 5) + return z // Esta linha faz Z retornar o valor de foo! + else + z + 2 // Esta linha retorna o valor de anonFunc + } + anonFunc(x) // Esta linha retorna o valor de foo +} + +///////////////////////////////////////////////// +// 3. Controle de Fluxo +///////////////////////////////////////////////// + +1 to 5 +val r = 1 to 5 +r.foreach(println) + +r foreach println +///N.B.: Scala é bem flexível quando se fala de pontos e parêntesis - estude as regras +//separadamente. Isso ajuda a escrever DSLs e APIs que são lidas como inglês. + +(5 to 1 by -1) foreach (println) + +// Um loop while +var i = 0 +while (i < 10) { println("i " + i); i += 1 } + +while (i < 10) { println("i " + i); i += 1 } // Sim, de novo. O que aconteceu? Por quê? + +i // Exibe o valor de i. Note que o while é um loop no senso clássico - + // executa sequencialmente enquanto muda a variável do loop. While é muito + // rápido, mas usar os combinadores e compreenões acima é mais fácil + // para entender e paralizar + +// Um loop do-while +i = 0 +do { + println("i ainda é menor que 10") + i += 1 +} while (i < 10) + + +// Recursão é a forma mais idiomática de repetir uma ação em Scala (assim como na +// maioria das linguagens de programação funcional) +// Funções recursivas precisam de um tipo de retorno explícito, o compilador não +// consegue inferir; +// Aqui está o Unit +def showNumbersInRange(a: Int, b: Int): Unit = { + print(a) + if (a < b) + showNumbersInRange(a + 1, b) +} +showNumbersInRange(1, 14) + +// Condicionais + +al x = 10 + +if (x == 1) println("yeah") +if (x == 10) println("yeah") +if (x == 11) println("yeah") +if (x == 11) println("yeah") else println("nay") + +println(if (x == 10) "yeah" else "nope") +val text = if (x == 10) "yeah" else "nope" + +///////////////////////////////////////////////// +// 4. Estrutura de Dados +///////////////////////////////////////////////// + +val a = Array(1, 2, 3, 5, 8, 13) +a(0) // Int = 1 +a(3) // Int = 5 +a(21) // Lança uma exceção + +val safeM = m.withDefaultValue("no lo se") +safeM("bottle") // java.lang.String = no lo se + +val s = Set(1, 3, 7) +s(0) // Boolean = false +s(1) // Boolean = true + +/* Veja a documantação do map aqui - + * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map + * e garanta que você leia + */ + + // Tuplas + + (1, 2) + + (4, 3, 2) + + (1, 2, "three") + + (a, 2, "three") + + //Por que ter isso? + val divideInts = (x: Int, y: Int) => (x / y, x % y) + +//A função divideInts te dá o resultado e o resultado +divideInts(10, 3) // (Int, Int) = (3,1) + +//Para acessar os elementos de uma tupla, use _._n onde n é o índex do elemento + +val d = divideInts(10, 3) // (Int, Int) = (3,1) + +d._1 // Int = 3 +d._2 // Int = 1 + +// Alternativamente, você pode atribuir múltiplas variáveis para uma tupla, o +// que é mais conveniente e legível em muitos casos +val (div, mod) = divideInts(10, 3) + +div // Int = 3 +mod // Int = 1 + +///////////////////////////////////////////////// +// 5. Object Oriented Programming +///////////////////////////////////////////////// + +/* + Tudo o que vimos até agora neste tutorial foram expressões simples (valores, funções, etc). + Essas expressões são boas para digitar no interpretador da linha de comando para + testes rápidos, mas elas não podem existir por si só em um arquivo Scala. Por exemplo, + você não pode ter simplesmente "val x = 5" em um arquivo Scala. Ao invés disso, os únicos + construtores de alto nível permitidos em Scala são: + + - objects + - classes + - case classes + - traits + + E agora vamos explicar o que é cada um deles. +*/ + +//classes são similares a classes em outras linguagens. Os argumentos do construtor +// são declarados logo depois do nome da classe e a inicialização é feita no corpo da classe. + +class Dog(br: String) { + // codigo do construtor aqui + var breed: String = br + + // Define um método chamado bark que retorna uma String + def bark = "Woof, woof!" + + // Assume-se que os métodos e valores são públicos. As palavras chave "protected" + // e "private" também estão disponíveis. + private def sleep(hours: Int) = + println(s"I'm sleeping for $hours hours") + + // Métodos abstratos são simplesmente métodos sem corpo. Se a gente remover o + // comentário da próxima linha a classe Dog teria que ser declarada como abstrata + + // abstract class Dog(...) { ... } + // def chaseAfter(what: String): String +} + +// A palavra chave "object" cria um tipo e uma instância singlenton desse tipo. +// É comum para classes em Scala ter um "companion object" (objeto companheiro), +// onde, por exemlo, o comportamento é capturado pelas classes em si, mas o comportamento +// relacionado a toda instância da classe vai em objects. A diferença é semelhante +// a métodos versus métodos estáticos em outras linguagens. Note que objects e +// classes podem ter o mesmo nome. + +object Dog { + def allKnownBreeds = List("pitbull", "shepherd", "retriever") + def createDog(breed: String) = new Dog(breed) +} + +// Case classes são classes que possuem uma funcionalidade extra incorporada. +// Uma dúvida comum para iniciantes em Scala é quando usar classes e quando usar +// case classes. A linha é bem tênue, mas em geral classes tendem a focar em encapsulamento, +// polimorfismo e comportamento. Os valores nestas classes tendem a ser privados e +// apenas métodos ficam expostos. O propósito primário de uma case class é guardar +// dados imutáveis. Às vezes as case classes possuem alguns poucos métodos, os quais +// raramente possuem efeitos colaterais (side effects). +case class Person(name: String, phoneNumber: String) + +// Cria uma nova instância. Observe que case classes não precisam de usar "new" ao serem instanciadas +val george = Person("George", "1234") +val kate = Person("Kate", "4567") + +// Com case classes você ganha algumas regalias, como getters: +// With case classes, you get a few perks for free, like getters: +george.phoneNumber // => "1234" + +// Verificação de igualdade por campo (sem a necessidade de sobrescrever o método equals) +Person("George", "1234") == Person("Kate", "1236") // => false + +// Uma maneira fácil de copiar +// otherGeorge == Person("george", "9876") +val otherGeorge = george.copy(phoneNumber = "9876") + +// E muitas outras. Case classes também possuem pattern matching de graça. Veja no próximo tópico. + +// Traits a caminho. + + +///////////////////////////////////////////////// +// 6. Pattern Matching +///////////////////////////////////////////////// + +// Pattern matching é um recurso muito poderoso e muito usado em Scala. Aqui +// mostramos como o seu pattern se adequa a uma case class. +// NB: Diferente de outras linguagens, Scala não precisa de quebras. Entrar em +// todas as condições do pattern matching simples não acontece. + +def matchPerson(person: Person): String = person match { + // Enrão você especifica os padrões + case Person("George", number) => "We found George! His number is " + number + case Person("Kate", number) => "We found Kate! Her number is " + number + case Person(name, number) => "We matched someone : " + name + ", phone : " + number +} + +val email = "(.*)@(.*)".r // Define uma regex para o próximo exemplo. + +// Pattern matching pode parecer com o comando switch nas liguagens da família C, +// mas é muito mais poderoso. Em Scala você pode encontrar mais correpondências: + +def matchEverything(obj: Any): String = obj match { + // Você pode encontrar valores correspondentes: + case "Hello world" => "Got the string Hello world" + + // Você pode fazer correspondência por tipo: + case x: Double => "Got a Double: " + x + + // Você pode especificar condições: + case x: Int if x > 10000 => "Got a pretty big number!" + + // Você pode encontrar correspondência com case classes, como fizemos antes: + case Person(name, number) => s"Got contact info for $name!" + + // Você pode encontrar correspondências por regex: + case email(name, domain) => s"Got email address $name@$domain" + + // Você pode encontrar correspondencias por tuplas: + case (a: Int, b: Double, c: String) => s"Got a tuple: $a, $b, $c" + + // Você pode encontrar corresponências por estruturas de dados: + case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c" + + // Você pode aninhar padrões: + case List(List((1, 2, "YAY"))) => "Got a list of list of tuple" + + // Retornar qualquer valor (padrão - default) caso nenhuma das possibilidades é correspondente. + case _ => "Got unknown object" + + // Na verdade, você pode fazer correspondência de padrão de qualquer objeto que + // tenha o método "unnaply". Este recurso é tão poderoso que o Scala te deixa + // criar funções inteiras como patterns: + + val patternFunc: Person => String = { + case Person("George", number) => s"George's number: $number" + case Person(name, number) => s"Random person's number: $number" + } +} + +///////////////////////////////////////////////// +// 7. Programação Funcional +///////////////////////////////////////////////// + +// Scala permite que métodos e funções recebam ou retornem outras funções ou métodos. + +val add10: Int => Int = _ + 10 // A function taking an Int and returning an Int +List(1, 2, 3) map add10 // List(11, 12, 13) - add10 is applied to each element + +// Funções anônimas podem ser usadas ao invés de funções com nomes: +List(1, 2, 3) map (x => x + 10) + +// E o símbolo underline ("_") pode ser usado quando há apenas um argumento para a função anônima. +List(1, 2, 3) map (_ + 10) + +// Se tanto o bloco animo quanto a função que você estiver usando receberem apenas +// um argumento, você pode inclusive omitir o símbolo _ +List(1, 2, 3) map (_ + 10) + +// Combinadores + +s.map(sq) + +val sSquared = s. map(sq) + +sSquared.filter(_ < 10) + +sSquared.reduce (_+_) + +// A função filter recebe um predicado (uma função do tipo A -> Boolean) e seleciona +// todos os elementos que satisfazem o predicado. +List(1, 2, 3) filter (_ > 2) // List(3) +case class Person(name: String, age: Int) +List( + Person(name = "Dom", age = 23), + Person(name = "Bob", age = 30) +).filter(_.age > 25) // List(Person("Bob", 30)) + +// Scala tem o método foreach definido em algumas collections em específico, o qual +// recebe um tipo e retorna Unit (um método void) +val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100) +aListOfNumbers foreach (x => println(x)) +aListOfNumbers foreach println + +/* NB Ests não são laços for. A semântica dos laços for é 'repetir' enquanto um + for-comprehension define um relacionamento entre dois conjuntos de dados */ + + +///////////////////////////////////////////////// +// 8. Implicits +///////////////////////////////////////////////// + +/* ALERTA ALERTA: + Implicits são um conjunto de recursos poderosos de Scala e consequentemente é + fácil abusar deles. Iniciantes em Scala deveriam resistir a tentação de usá-los + até que eles entendam não apenas como eles funcionam mas também as melhores práticas + deles. Incluimos uma sessão neste tutorial sobre isso porque implicits são tão + corriqueiros em bibliotecas do Scala que é impossível fazer qualqeuer coisa expressiva + sem utilizar uma biblioteca que usa implicits. Isto é para você entender e trabalhar + com implicits. Não declare seus próprios implicits por conta própria. +*/ + +// qualquer valor (val, function, objects, etc) pode ser declarado para ser implícito +// usando a, você adivinhou, palavra chave "implicit". Usaremos a classe Dog definida +// na sessão 5 para os próximos exemplos. +implicit val myImplicitInt = 100 +implicit def myImplicitFunction(breed: String) = new Dog("Golden " + breed) + +// A palavra chave implicit não muda o comportamento do valor por si só, então +// os valores acima podem ser usados como de costume. +myImplicitInt + 2 // => 102 +myImplicitFunction("Pitbull").breed // => "Golden Pitbull" + +A diferença é que agora esses valores são elegíveis para serem usados quando outra +// parte do código "precisa" de um valor implícito. Uma situação é uma função +// com argumentos implícitos: +def sendGreetings(toWhom: String)(implicit howMany: Int) = + s"Hello $toWhom, $howMany blessings to you and yours!" + +// Se fornecermos um valor para "howMany" a função se comporta como sempre +sendGreetings("John")(1000) // => "Hello John, 1000 blessings to you and yours!" + +// Mas se omitirmos o parâmetro implícito um valor implícito de mesmo tipo é usado, +// neste caso, "myImplicitInt": +sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!" + +// Parâmetros implícitos de funções nos permitem simular type classes em outras +//linguagens funcionais. As linhas abaixo são a mesma coisa: +// def foo[T](implicit c: C[T]) = ... +// def foo[T : C] = ... + +// Outro caso no qual o compilador procura por um implicit é quando você tem obj.method(...) +// mas "obj" não possui "method" como um método. Neste caso, se houver uma conversão +// de implicit do tipo A => B, onde A é o tipo do "obj" e B tem um método chamado +// "method", a conversão é aplicada. Então, tendo myImplicitFunction acima em escopo, podemos dizer: +"Retriever".breed // => "Golden Retriever" +"Sheperd".bark // => "Woof, woof!" + +// Aqui, a String é convertida para Dog usando nossa função acima, então o método +// apropriado é chamado. Isso é um recurso extremamente poderoso, mas de novo, não +// é para ser usado de maneira leviana. Na verdade, quando você define a função +// implícita, o seu compilador deve exibir um aviso de que você não deveria fazer isso, +// a menos que você realmente saiba o que você está fazendo. + +///////////////////////////////////////////////// +// 9. Misc +///////////////////////////////////////////////// + +// Importando coisas +import scala.collection.immutable.List + +// Importando todos os sub pacotes +import scala.collection.immutable._ + +// Importando várias classes em um único comando +import scala.collection.immutable.{List, Map} + +// Renomeando um import usando '=>' +import scala.collection.immutable.{List => ImmutableList} + +// Importa todas as classes, com exceção de algumas. O import abaixo importa todas as classes excluindo Map e Set: +import scala.collection.immutable.{Map => _, Set => _, _} + +// Classes Java também podem ser importadas. A syntaxe de Scala pode ser usada: +import java.swing.{JFrame, JWindow} + +// O ponto de entrada do seu programa é definido em um arquivo Scala usando um object com um único método main: +object Application { + def main(args: Array[String]): Unit = { + // o código fica aqui + } +} + +// Arquivos podem ter múltiplas classes e objects. Compile com scalac + +// Entrada e saída + +// Para ler um arquivo linha a linha +import scala.io.Source +for(line <- Source.fromFile("myfile.txt").getLines()) + println(line) + +// Para escrever um arquivo use o PrintWriter do Javaval writer = new PrintWriter("myfile.txt") +writer.write("Writing line for line" + util.Properties.lineSeparator) +writer.write("Another line here" + util.Properties.lineSeparator) +writer.close() + +## Recursos adicionais + +* [Scala for the impatient](http://horstmann.com/scala/) +* [Twitter Scala school](http://twitter.github.io/scala_school/) +* [Documentação de Scala](http://docs.scala-lang.org/) +* [Tente Scala no seu navegador](http://scalatutorials.com/tour/) +* Junte [Scala user group](https://groups.google.com/forum/#!forum/scala-user) +``` diff --git a/purescript.html.markdown b/purescript.html.markdown index b413a9e3..19346760 100644 --- a/purescript.html.markdown +++ b/purescript.html.markdown @@ -85,7 +85,7 @@ head [1,2,3] -- Just (1) tail [3,2,1] -- Just ([2,1]) init [1,2,3] -- Just ([1,2]) last [3,2,1] -- Just (1) --- Random access - indexing +-- Array access - indexing [3,4,5,6,7] !! 2 -- Just (5) -- Range 1..5 -- [1,2,3,4,5] diff --git a/python.html.markdown b/python.html.markdown index 55f56071..bd6090c7 100644 --- a/python.html.markdown +++ b/python.html.markdown @@ -5,6 +5,7 @@ contributors: - ["Amin Bandali", "http://aminbandali.com"] - ["Andre Polykanine", "https://github.com/Oire"] - ["evuez", "http://github.com/evuez"] + - ["habi", "http://github.com/habi"] filename: learnpython.py --- @@ -34,9 +35,8 @@ Python 3 tutorial. as comments """ - #################################################### -## 1. Primitive Datatypes and Operators +# 1. Primitive Datatypes and Operators #################################################### # You have numbers @@ -53,41 +53,42 @@ Python 3 tutorial. 5 / 2 # => 2 # To fix division we need to learn about floats. -2.0 # This is a float +2.0 # This is a float 11.0 / 4.0 # => 2.75 ahhh...much better # Result of integer division truncated down both for positive and negative. -5 // 3 # => 1 -5.0 // 3.0 # => 1.0 # works on floats too +5 // 3 # => 1 +5.0 // 3.0 # => 1.0 # works on floats too -5 // 3 # => -2 --5.0 // 3.0 # => -2.0 +-5.0 // 3.0 # => -2.0 # Note that we can also import division module(Section 6 Modules) # to carry out normal division with just one '/'. from __future__ import division -11/4 # => 2.75 ...normal division -11//4 # => 2 ...floored division + +11 / 4 # => 2.75 ...normal division +11 // 4 # => 2 ...floored division # Modulo operation -7 % 3 # => 1 +7 % 3 # => 1 # Exponentiation (x to the yth power) -2**4 # => 16 +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 +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 +0 and 2 # => 0 +-5 or 0 # => -5 +0 == False # => True +2 == True # => False +1 == True # => True # negate with not not True # => False @@ -129,12 +130,12 @@ not False # => True # You can find the length of a string len("This is a string") # => 16 -#String formatting with % -#Even though the % string operator will be deprecated on Python 3.1 and removed -#later at some time, it may still be good to know how it works. +# String formatting with % +# Even though the % string operator will be deprecated on Python 3.1 and removed +# later at some time, it may still be good to know how it works. x = 'apple' y = 'lemon' -z = "The items in the basket are %s and %s" % (x,y) +z = "The items in the basket are %s and %s" % (x, y) # A newer way to format strings is the format method. # This method is the preferred way @@ -170,20 +171,21 @@ bool("") # => False #################################################### -## 2. Variables and Collections +# 2. Variables and Collections #################################################### # Python has a print statement -print "I'm Python. Nice to meet you!" # => I'm Python. Nice to meet you! +print "I'm Python. Nice to meet you!" # => I'm Python. Nice to meet you! # Simple way to get input data from console -input_string_var = raw_input("Enter some data: ") # Returns the data as a string -input_var = input("Enter some data: ") # Evaluates the data as python code +input_string_var = raw_input( + "Enter some data: ") # Returns the data as a string +input_var = input("Enter some data: ") # Evaluates the data as python code # Warning: Caution is recommended for input() method usage # Note: In python 3, input() is deprecated and raw_input() is renamed to input() # No need to declare variables before assigning to them. -some_var = 5 # Convention is to use lower_case_with_underscores +some_var = 5 # Convention is to use lower_case_with_underscores some_var # => 5 # Accessing a previously unassigned variable is an exception. @@ -194,21 +196,20 @@ some_other_var # Raises a name error # Equivalent of C's '?:' ternary operator "yahoo!" if 3 > 2 else 2 # => "yahoo!" - # Lists store sequences li = [] # You can start with a prefilled list other_li = [4, 5, 6] # Add stuff to the end of a list with append -li.append(1) # li is now [1] -li.append(2) # li is now [1, 2] -li.append(4) # li is now [1, 2, 4] -li.append(3) # li is now [1, 2, 4, 3] +li.append(1) # li is now [1] +li.append(2) # li is now [1, 2] +li.append(4) # li is now [1, 2, 4] +li.append(3) # li is now [1, 2, 4, 3] # Remove from the end with pop -li.pop() # => 3 and li is now [1, 2, 4] +li.pop() # => 3 and li is now [1, 2, 4] # Let's put it back -li.append(3) # li is now [1, 2, 4, 3] again. +li.append(3) # li is now [1, 2, 4, 3] again. # Access a list like you would any array li[0] # => 1 @@ -230,21 +231,21 @@ li[2:] # => [4, 3] # Omit the end li[:3] # => [1, 2, 4] # Select every second entry -li[::2] # =>[1, 4] +li[::2] # =>[1, 4] # Reverse a copy of the list -li[::-1] # => [3, 4, 2, 1] +li[::-1] # => [3, 4, 2, 1] # Use any combination of these to make advanced slices # li[start:end:step] # Remove arbitrary elements from a list with "del" -del li[2] # li is now [1, 2, 3] +del li[2] # li is now [1, 2, 3] # You can add lists -li + other_li # => [1, 2, 3, 4, 5, 6] +li + other_li # => [1, 2, 3, 4, 5, 6] # Note: values for li and for other_li are not modified. # Concatenate lists with "extend()" -li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6] +li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6] # Remove first occurrence of a value li.remove(2) # li is now [1, 3, 4, 5, 6] @@ -258,31 +259,29 @@ li.index(2) # => 1 li.index(7) # Raises a ValueError as 7 is not in the list # Check for existence in a list with "in" -1 in li # => True +1 in li # => True # Examine the length with "len()" -len(li) # => 6 - +len(li) # => 6 # Tuples are like lists but are immutable. tup = (1, 2, 3) -tup[0] # => 1 +tup[0] # => 1 tup[0] = 3 # Raises a TypeError # You can do all those list thingies on tuples too -len(tup) # => 3 -tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6) -tup[:2] # => (1, 2) -2 in tup # => True +len(tup) # => 3 +tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6) +tup[:2] # => (1, 2) +2 in tup # => True # You can unpack tuples (or lists) into variables -a, b, c = (1, 2, 3) # a is now 1, b is now 2 and c is now 3 -d, e, f = 4, 5, 6 # you can leave out the parentheses +a, b, c = (1, 2, 3) # a is now 1, b is now 2 and c is now 3 +d, e, f = 4, 5, 6 # you can leave out the parentheses # Tuples are created by default if you leave out the parentheses -g = 4, 5, 6 # => (4, 5, 6) +g = 4, 5, 6 # => (4, 5, 6) # Now look how easy it is to swap two values -e, d = d, e # d is now 5 and e is now 4 - +e, d = d, e # d is now 5 and e is now 4 # Dictionaries store mappings empty_dict = {} @@ -290,33 +289,33 @@ empty_dict = {} filled_dict = {"one": 1, "two": 2, "three": 3} # Look up values with [] -filled_dict["one"] # => 1 +filled_dict["one"] # => 1 # Get all keys as a list with "keys()" -filled_dict.keys() # => ["three", "two", "one"] +filled_dict.keys() # => ["three", "two", "one"] # Note - Dictionary key ordering is not guaranteed. # Your results might not match this exactly. # Get all values as a list with "values()" -filled_dict.values() # => [3, 2, 1] +filled_dict.values() # => [3, 2, 1] # Note - Same as above regarding key ordering. # Get all key-value pairs as a list of tuples with "items()" -filled_dicts.items() # => [("one", 1), ("two", 2), ("three", 3)] +filled_dicts.items() # => [("one", 1), ("two", 2), ("three", 3)] # Check for existence of keys in a dictionary with "in" -"one" in filled_dict # => True -1 in filled_dict # => False +"one" in filled_dict # => True +1 in filled_dict # => False # Looking up a non-existing key is a KeyError -filled_dict["four"] # KeyError +filled_dict["four"] # KeyError # Use "get()" method to avoid the KeyError -filled_dict.get("one") # => 1 -filled_dict.get("four") # => None +filled_dict.get("one") # => 1 +filled_dict.get("four") # => None # The get method supports a default argument when the value is missing -filled_dict.get("one", 4) # => 1 -filled_dict.get("four", 4) # => 4 +filled_dict.get("one", 4) # => 1 +filled_dict.get("four", 4) # => 4 # note that filled_dict.get("four") is still => None # (get doesn't set the value in the dictionary) @@ -327,47 +326,46 @@ filled_dict["four"] = 4 # now, filled_dict["four"] => 4 filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5 filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5 - # Sets store ... well sets (which are like lists but can contain no duplicates) empty_set = set() # Initialize a "set()" with a bunch of values -some_set = set([1, 2, 2, 3, 4]) # some_set is now set([1, 2, 3, 4]) +some_set = set([1, 2, 2, 3, 4]) # some_set is now set([1, 2, 3, 4]) # order is not guaranteed, even though it may sometimes look sorted another_set = set([4, 3, 2, 2, 1]) # another_set is now set([1, 2, 3, 4]) # Since Python 2.7, {} can be used to declare a set -filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4} +filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4} # Add more items to a set -filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5} +filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5} # Do set intersection with & other_set = {3, 4, 5, 6} -filled_set & other_set # => {3, 4, 5} +filled_set & other_set # => {3, 4, 5} # Do set union with | -filled_set | other_set # => {1, 2, 3, 4, 5, 6} +filled_set | other_set # => {1, 2, 3, 4, 5, 6} # Do set difference with - -{1, 2, 3, 4} - {2, 3, 5} # => {1, 4} +{1, 2, 3, 4} - {2, 3, 5} # => {1, 4} # Do set symmetric difference with ^ {1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5} # Check if set on the left is a superset of set on the right -{1, 2} >= {1, 2, 3} # => False +{1, 2} >= {1, 2, 3} # => False # Check if set on the left is a subset of set on the right -{1, 2} <= {1, 2, 3} # => True +{1, 2} <= {1, 2, 3} # => True # Check for existence in a set with in -2 in filled_set # => True -10 in filled_set # => False +2 in filled_set # => True +10 in filled_set # => False #################################################### -## 3. Control Flow +# 3. Control Flow #################################################### # Let's just make a variable @@ -377,12 +375,11 @@ some_var = 5 # prints "some_var is smaller than 10" if some_var > 10: print "some_var is totally bigger than 10." -elif some_var < 10: # This elif clause is optional. +elif some_var < 10: # This elif clause is optional. print "some_var is smaller than 10." -else: # This is optional too. +else: # This is optional too. print "some_var is indeed 10." - """ For loops iterate over lists prints: @@ -438,12 +435,12 @@ try: # Use "raise" to raise an error raise IndexError("This is an index error") except IndexError as e: - pass # Pass is just a no-op. Usually you would do recovery here. + pass # Pass is just a no-op. Usually you would do recovery here. except (TypeError, NameError): - pass # Multiple exceptions can be handled together, if required. -else: # Optional clause to the try/except block. Must follow all except blocks - print "All good!" # Runs only if the code in try raises no exceptions -finally: # Execute under all circumstances + pass # Multiple exceptions can be handled together, if required. +else: # Optional clause to the try/except block. Must follow all except blocks + print "All good!" # Runs only if the code in try raises no exceptions +finally: # Execute under all circumstances print "We can clean up resources here" # Instead of try/finally to cleanup resources you can use a with statement @@ -453,19 +450,20 @@ with open("myfile.txt") as f: #################################################### -## 4. Functions +# 4. Functions #################################################### # Use "def" to create new functions def add(x, y): print "x is {0} and y is {1}".format(x, y) - return x + y # Return values with a return statement + return x + y # Return values with a return statement + # Calling functions with parameters -add(5, 6) # => prints out "x is 5 and y is 6" and returns 11 +add(5, 6) # => prints out "x is 5 and y is 6" and returns 11 # Another way to call functions is with keyword arguments -add(y=6, x=5) # Keyword arguments can arrive in any order. +add(y=6, x=5) # Keyword arguments can arrive in any order. # You can define functions that take a variable number of @@ -473,21 +471,26 @@ add(y=6, x=5) # Keyword arguments can arrive in any order. def varargs(*args): return args -varargs(1, 2, 3) # => (1, 2, 3) + +varargs(1, 2, 3) # => (1, 2, 3) + # You can define functions that take a variable number of # keyword args, as well, which will be interpreted as a dict by using ** def keyword_args(**kwargs): return kwargs + # Let's call it to see what happens -keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"} +keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"} # You can do both at once, if you like def all_the_args(*args, **kwargs): print args print kwargs + + """ all_the_args(1, 2, a=3, b=4) prints: (1, 2) @@ -498,9 +501,10 @@ all_the_args(1, 2, a=3, b=4) prints: # Use * to expand positional args and use ** to expand keyword args. args = (1, 2, 3, 4) kwargs = {"a": 3, "b": 4} -all_the_args(*args) # equivalent to foo(1, 2, 3, 4) -all_the_args(**kwargs) # equivalent to foo(a=3, b=4) -all_the_args(*args, **kwargs) # equivalent to foo(1, 2, 3, 4, a=3, b=4) +all_the_args(*args) # equivalent to foo(1, 2, 3, 4) +all_the_args(**kwargs) # equivalent to foo(a=3, b=4) +all_the_args(*args, **kwargs) # equivalent to foo(1, 2, 3, 4, a=3, b=4) + # you can pass args and kwargs along to other functions that take args/kwargs # by expanding them with * and ** respectively @@ -509,58 +513,64 @@ def pass_all_the_args(*args, **kwargs): print varargs(*args) print keyword_args(**kwargs) + # Function Scope x = 5 + def set_x(num): # Local var x not the same as global variable x - x = num # => 43 - print x # => 43 + x = num # => 43 + print x # => 43 + def set_global_x(num): global x - print x # => 5 - x = num # global var x is now set to 6 - print x # => 6 + print x # => 5 + x = num # global var x is now set to 6 + print x # => 6 + set_x(43) set_global_x(6) + # Python has first class functions def create_adder(x): def adder(y): return x + y + return adder + add_10 = create_adder(10) -add_10(3) # => 13 +add_10(3) # => 13 # There are also anonymous functions -(lambda x: x > 2)(3) # => True -(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5 +(lambda x: x > 2)(3) # => True +(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5 # There are built-in higher order functions -map(add_10, [1, 2, 3]) # => [11, 12, 13] -map(max, [1, 2, 3], [4, 2, 1]) # => [4, 2, 3] +map(add_10, [1, 2, 3]) # => [11, 12, 13] +map(max, [1, 2, 3], [4, 2, 1]) # => [4, 2, 3] -filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7] +filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7] # We can use list comprehensions for nice maps and filters [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] +[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7] # You can construct set and dict comprehensions as well. -{x for x in 'abcddeef' if x in 'abc'} # => {'d', 'e', 'f'} -{x: x**2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} +{x for x in 'abcddeef' if x in 'abc'} # => {'a', 'b', 'c'} +{x: x ** 2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} #################################################### -## 5. Classes +# 5. Classes #################################################### # We subclass from object to get a class. class Human(object): - # A class attribute. It is shared by all instances of this class species = "H. sapiens" @@ -575,7 +585,6 @@ class Human(object): # Initialize property self.age = 0 - # An instance method. All methods take "self" as the first argument def say(self, msg): return "{0}: {1}".format(self.name, msg) @@ -611,45 +620,46 @@ class Human(object): # Instantiate a class i = Human(name="Ian") -print i.say("hi") # prints out "Ian: hi" +print i.say("hi") # prints out "Ian: hi" j = Human("Joel") print j.say("hello") # prints out "Joel: hello" # Call our class method -i.get_species() # => "H. sapiens" +i.get_species() # => "H. sapiens" # Change the shared attribute Human.species = "H. neanderthalensis" -i.get_species() # => "H. neanderthalensis" -j.get_species() # => "H. neanderthalensis" +i.get_species() # => "H. neanderthalensis" +j.get_species() # => "H. neanderthalensis" # Call the static method -Human.grunt() # => "*grunt*" +Human.grunt() # => "*grunt*" # Update the property i.age = 42 # Get the property -i.age # => 42 +i.age # => 42 # Delete the property del i.age i.age # => raises an AttributeError - #################################################### -## 6. Modules +# 6. Modules #################################################### # You can import modules import math + print math.sqrt(16) # => 4 # You can get specific functions from a module from math import ceil, floor + print ceil(3.7) # => 4.0 -print floor(3.7) # => 3.0 +print floor(3.7) # => 3.0 # You can import all functions from a module. # Warning: this is not recommended @@ -657,9 +667,11 @@ from math import * # You can shorten module names import math as m -math.sqrt(16) == m.sqrt(16) # => True + +math.sqrt(16) == m.sqrt(16) # => True # you can also test that the functions are equivalent from math import sqrt + math.sqrt == m.sqrt == sqrt # => True # Python modules are just ordinary python files. You @@ -669,8 +681,10 @@ math.sqrt == m.sqrt == sqrt # => True # You can find out which functions and attributes # defines a module. import math + dir(math) + # If you have a Python script named math.py in the same # folder as your current script, the file math.py will # be loaded instead of the built-in Python module. @@ -679,7 +693,7 @@ dir(math) #################################################### -## 7. Advanced +# 7. Advanced #################################################### # Generators @@ -692,6 +706,8 @@ def double_numbers(iterable): double_arr = [] for i in iterable: double_arr.append(i + i) + return double_arr + # Running the following would mean we'll double all values first and return all # of them back to be checked by our condition @@ -700,12 +716,14 @@ for value in double_numbers(range(1000000)): # `test_non_generator` if value > 5: break + # We could instead use a generator to "generate" the doubled value as the item # is being requested def double_numbers_generator(iterable): for i in iterable: yield i + i + # Running the same code as before, but with a generator, now allows us to iterate # over the values and doubling them one by one as they are being consumed by # our logic. Hence as soon as we see a value > 5, we break out of the @@ -723,22 +741,22 @@ for value in double_numbers_generator(xrange(1000000)): # `test_generator` # Just as you can create a list comprehension, you can create generator # comprehensions as well. -values = (-x for x in [1,2,3,4,5]) +values = (-x for x in [1, 2, 3, 4, 5]) for x in values: print(x) # prints -1 -2 -3 -4 -5 to console/terminal # You can also cast a generator comprehension directly to a list. -values = (-x for x in [1,2,3,4,5]) +values = (-x for x in [1, 2, 3, 4, 5]) gen_to_list = list(values) print(gen_to_list) # => [-1, -2, -3, -4, -5] - # Decorators # in this example beg wraps say # Beg will call say. If say_please is True then it will change the returned # message from functools import wraps + def beg(target_function): @wraps(target_function) def wrapper(*args, **kwargs): @@ -749,11 +767,13 @@ def beg(target_function): return wrapper + @beg def say(say_please=False): msg = "Can you buy me a beer?" return msg, say_please + print say() # Can you buy me a beer? print say(say_please=True) # Can you buy me a beer? Please! I am poor :( ``` diff --git a/python3.html.markdown b/python3.html.markdown index 839d66fd..02745117 100644 --- a/python3.html.markdown +++ b/python3.html.markdown @@ -71,11 +71,14 @@ True and False # => False False or True # => True # Note using Bool operators with ints +# False is 0 and True is 1 +# Don't mix up with bool(ints) and bitwise and/or (&,|) 0 and 2 # => 0 -5 or 0 # => -5 0 == False # => True 2 == True # => False 1 == True # => True +-5 != False != True #=> True # Equality is == 1 == 1 # => True @@ -143,13 +146,13 @@ None # => None "etc" is None # => False None is None # => True -# None, 0, and empty strings/lists/dicts all evaluate to False. +# None, 0, and empty strings/lists/dicts/tuples all evaluate to False. # All other values are True bool(0) # => False bool("") # => False bool([]) # => False bool({}) # => False - +bool(()) # => False #################################################### ## 2. Variables and Collections @@ -491,7 +494,7 @@ next(our_iterator) # => "one" next(our_iterator) # => "two" next(our_iterator) # => "three" -# After the iterator has returned all of its data, it gives you a StopIterator Exception +# After the iterator has returned all of its data, it gives you a StopIteration Exception next(our_iterator) # Raises StopIteration # You can grab all the elements of an iterator by calling list() on it. diff --git a/racket.html.markdown b/racket.html.markdown index 96dcaf25..38335bc1 100644 --- a/racket.html.markdown +++ b/racket.html.markdown @@ -164,10 +164,17 @@ my-pet ; => #<dog> (cons 1 (cons 2 (cons 3 null))) ; => '(1 2 3) ;; `list' is a convenience variadic constructor for lists (list 1 2 3) ; => '(1 2 3) -;; and a quote can also be used for a literal list value +;; a quote can also be used for a literal list value '(1 2 3) ; => '(1 2 3) +;; a quasiquote (represented by the backtick character) with commas +;; can be used to evaluate functions +`(1 ,(+ 1 1) 3) ; => '(1 2 3) -;; Racket has predefined functions on top of car and cdr, to extract parts of a list +;; With lists, car/cdr work slightly differently +(car '(1 2 3)) ; => 1 +(cdr '(1 2 3)) ; => '(2 3) + +;; Racket also has predefined functions on top of car and cdr, to extract parts of a list (cadr (list 1 2 3)) ; => 2 (car (cdr (list 1 2 3))) ; => 2 diff --git a/red.html.markdown b/red.html.markdown index 6d10fe8f..0c979ce1 100644 --- a/red.html.markdown +++ b/red.html.markdown @@ -34,7 +34,8 @@ brackets can be filled with useful information about this script or program: the author's name, the filename, the version, the license, a summary of what the program does or any other files it needs. The red/System header is just like the red header, only saying "red/System" and not "red". - +``` +```red Red [] ;this is a commented line diff --git a/rst.html.markdown b/rst.html.markdown index 161a0610..59a29daa 100644 --- a/rst.html.markdown +++ b/rst.html.markdown @@ -2,12 +2,13 @@ language: restructured text contributors: - ["DamienVGN", "https://github.com/martin-damien"] + - ["Andre Polykanine", "https://github.com/Oire"] filename: restructuredtext.rst --- -RST is file format formely created by Python community to write documentation (and so, is part of Docutils). +RST is a file format formely created by Python community to write documentation (and so, is part of Docutils). -RST files are simple text files with lightweight syntaxe (comparing to HTML). +RST files are simple text files with lightweight syntax (comparing to HTML). ## Installation @@ -20,25 +21,25 @@ To use Restructured Text, you will have to install [Python](http://www.python.or $ easy_install docutils ``` -If your system have `pip`, you can use it too: +If your system has `pip`, you can use it too: ```bash $ pip install docutils ``` -## File syntaxe +## File syntax A simple example of the file syntax: ```rst -.. Line with two dotes are special commands. But if no command can be found, the line is considered as a comment +.. Lines starting with two dots are special commands. But if no command can be found, the line is considered as a comment ========================================================= Main titles are written using equals signs over and under ========================================================= -Note that theire must be as many equals signs as title characters. +Note that there must be as many equals signs as title characters. Title are underlined with equals signs too ========================================== @@ -46,12 +47,12 @@ Title are underlined with equals signs too Subtitles with dashes --------------------- -And sub-subtitles with tilde +And sub-subtitles with tildes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can put text in *italic* or in **bold**, you can "mark" text as code with double backquote ``: ``print()``. -Lists are as simple as markdown: +Lists are as simple as in Markdown: - First item - Second item @@ -72,22 +73,22 @@ France Paris Japan Tokyo =========== ======== -More complexe tabless can be done easily (merged columns and/or rows) but I suggest you to read the complete doc for this :) +More complex tabless can be done easily (merged columns and/or rows) but I suggest you to read the complete doc for this :) -Their is multiple ways to make links: +There are multiple ways to make links: -- By adding an underscore after a word : Github_ and by adding the target after the text (this have the advantage to not insert un-necessary URL inside the readed text). -- By typing a full comprehensible URL : https://github.com/ (will be automatically converted in link) -- By making a more "markdown" link: `Github <https://github.com/>`_ . +- By adding an underscore after a word : Github_ and by adding the target URL after the text (this way has the advantage to not insert unnecessary URLs inside readable text). +- By typing a full comprehensible URL : https://github.com/ (will be automatically converted to a link) +- By making a more Markdown-like link: `Github <https://github.com/>`_ . .. _Github https://github.com/ ``` -## How to use it +## How to Use It -RST comes with docutils in which you have `rst2html` for exemple: +RST comes with docutils where you have `rst2html`, for example: ```bash $ rst2html myfile.rst output.html @@ -95,7 +96,7 @@ $ rst2html myfile.rst output.html *Note : On some systems the command could be rst2html.py* -But their is more complexe applications that uses RST file format: +But there are more complex applications that use the RST format: - [Pelican](http://blog.getpelican.com/), a static site generator - [Sphinx](http://sphinx-doc.org/), a documentation generator diff --git a/ru-ru/c++-ru.html.markdown b/ru-ru/c++-ru.html.markdown index 0cf580d5..cef5ab7e 100644 --- a/ru-ru/c++-ru.html.markdown +++ b/ru-ru/c++-ru.html.markdown @@ -304,7 +304,7 @@ someFun(tempObjectFun()); // Выполняет версию с временн basic_string(const basic_string& other); basic_string(basic_string&& other); -// Идея в том, что если мы конструируем новую строку из временного объекта (который +// Идея в том, что если мы конструируем новую строку из временного объекта (который // так или иначе будет уничтожен), мы можем использовать более эффективный конструктор, // который "спасает" части этой временной строки. Эта концепция была названа // "move semantics". @@ -329,7 +329,7 @@ ECarTypes GetPreferredCarType() } // На момент выхода C++11 есть простой способ назначения типа перечисления, что -// полезно в случае сериализации данных и преобразований между конечным типом и +// полезно в случае сериализации данных и преобразований между конечным типом и // соответствующими константами. enum ECarTypes : uint8_t { @@ -453,7 +453,7 @@ void Dog::print() const Dog::~Dog() { - cout << "Goodbye " << name << "\n"; + std::cout << "Goodbye " << name << "\n"; } int main() { @@ -521,7 +521,7 @@ public: // по умолчанию (0, 0) Point() { }; - // Следующий синтаксис известен как список инициализации и является верным способом + // Следующий синтаксис известен как список инициализации и является верным способом // инициализировать значения членов класса. Point (double a, double b) : x(a), @@ -793,7 +793,7 @@ void doSomethingWithAFile(const std::string& filename) // Весь идиоматический код на С++ широко использует RAII для всех ресурсов. // Дополнительные примеры включат: // - Использование памяти unique_ptr и shared_ptr -// - Контейнеры - стандартная библиотека связанных списков, векторы +// - Контейнеры - стандартная библиотека связанных списков, векторы // (т.е. самоизменяемые массивы), хэш-таблицы и все остальное автоматически // уничтожается сразу же, когда выходит за пределы области видимости. // - Ипользование мьютексов lock_guard и unique_lock diff --git a/ru-ru/html-ru.html.markdown b/ru-ru/html-ru.html.markdown index 5cf95fc4..5069d77f 100644 --- a/ru-ru/html-ru.html.markdown +++ b/ru-ru/html-ru.html.markdown @@ -5,6 +5,7 @@ contributors: - ["Christophe THOMAS", "https://github.com/WinChris"] translators: - ["Lana Tim", "https://github.com/LanaTim"] +lang: ru-ru --- HTML расшифровывается как Hypertext Markup Language(гипертекстовый язык разметки). diff --git a/sass.html.markdown b/sass.html.markdown index 860e550a..224db80e 100644 --- a/sass.html.markdown +++ b/sass.html.markdown @@ -16,7 +16,7 @@ This tutorial is written using SCSS. If you're already familiar with CSS3, you'll be able to pick up Sass relatively quickly. It does not provide any new styling properties but rather the tools to write your CSS more efficiently and make maintenance much easier. -```scss +```sass //Single line comments are removed when Sass is compiled to CSS. diff --git a/solidity.html.markdown b/solidity.html.markdown index 0ad8af32..5b0ac3a3 100644 --- a/solidity.html.markdown +++ b/solidity.html.markdown @@ -45,7 +45,7 @@ features are typically marked, and subject to change. Pull requests welcome. /* 'contract' has similarities to 'class' in other languages (class variables, inheritance, etc.) */ -contract SimpleBank { // CamelCase +contract SimpleBank { // CapWords // Declare state variables outside function, persist through life of contract // dictionary that maps addresses to balances diff --git a/tcl.html.markdown b/tcl.html.markdown index 9118081d..e3e84268 100644 --- a/tcl.html.markdown +++ b/tcl.html.markdown @@ -57,9 +57,9 @@ lighter that that of Lisp, just gets out of the way. ```tcl #! /bin/env tclsh -################################################################################ +############################################################################### ## 1. Guidelines -################################################################################ +############################################################################### # Tcl is not Bash or C! This needs to be said because standard shell quoting # habits almost work in Tcl and it is common for people to pick up Tcl and try @@ -72,9 +72,9 @@ lighter that that of Lisp, just gets out of the way. # are formatted as lists. -################################################################################ +############################################################################### ## 2. Syntax -################################################################################ +############################################################################### # Every line is a command. The first word is the name of the command, and # subsequent words are arguments to the command. Words are delimited by @@ -151,6 +151,8 @@ set greeting "Hello, [set {first name}]" # To promote the words within a word to individual words of the current # command, use the expansion operator, "{*}". +``` +```tcl set {*}{name Neo} # is equivalent to @@ -171,14 +173,15 @@ namespace eval people { } -#The full name of a variable includes its enclosing namespace(s), delimited by two colons: +# The full name of a variable includes its enclosing namespace(s), delimited by +# two colons: set greeting "Hello $people::person1::name" -################################################################################ +############################################################################### ## 3. A Few Notes -################################################################################ +############################################################################### # All other functionality is implemented via commands. From this point on, # there is no new syntax. Everything else there is to learn about Tcl is about @@ -192,10 +195,11 @@ set greeting "Hello $people::person1::name" namespace delete :: -# Because of name resolution behaviour, it's safer to use the "variable" command to -# declare or to assign a value to a namespace. If a variable called "name" already -# exists in the global namespace, using "set" here will assign a value to the global variable -# instead of creating a new variable in the local namespace. +# Because of name resolution behaviour, it's safer to use the "variable" +# command to declare or to assign a value to a namespace. If a variable called +# "name" already exists in the global namespace, using "set" here will assign +# a value to the global variable instead of creating a new variable in the +# local namespace. namespace eval people { namespace eval person1 { variable name Neo @@ -208,9 +212,9 @@ set people::person1::name Neo -################################################################################ +############################################################################### ## 4. Commands -################################################################################ +############################################################################### # Math can be done with the "expr" command. set a 3 @@ -264,7 +268,7 @@ proc fold {cmd args} { foreach arg $args { set res [$cmd $res $arg] } - return res + return $res } fold ::tcl::mathop::* 5 3 3 ;# -> 45 @@ -294,7 +298,8 @@ while {$i < 10} { } -# A list is a specially-formatted string. In the simple case, whitespace is sufficient to delimit values +# A list is a specially-formatted string. In the simple case, whitespace is +# sufficient to delimit values set amounts 10\ 33\ 18 set amount [lindex $amounts 1] @@ -406,7 +411,7 @@ proc set_double {varname value} { } -#get rid of the built-in "while" command. +# Get rid of the built-in "while" command. rename ::while {} diff --git a/tr-tr/swift-tr.html.markdown b/tr-tr/swift-tr.html.markdown index 15056bb8..e694d95d 100644 --- a/tr-tr/swift-tr.html.markdown +++ b/tr-tr/swift-tr.html.markdown @@ -2,7 +2,7 @@ language: swift contributors: - ["Özgür Şahin", "https://github.com/ozgurshn/"] -filename: learnswift.swift +filename: learnswift-tr.swift lang: tr-tr --- diff --git a/typescript.html.markdown b/typescript.html.markdown index 1d712369..d3ca0786 100644 --- a/typescript.html.markdown +++ b/typescript.html.markdown @@ -13,7 +13,7 @@ This article will focus only on TypeScript extra syntax, as opposed to [JavaScri To test TypeScript's compiler, head to the [Playground] (http://www.typescriptlang.org/Playground) where you will be able to type code, have auto completion and directly see the emitted JavaScript. -```js +```ts // There are 3 basic types in TypeScript var isDone: boolean = false; var lines: number = 42; @@ -46,10 +46,12 @@ function bigHorribleAlert(): void { var f1 = function(i: number): number { return i * i; } // Return type inferred var f2 = function(i: number) { return i * i; } +// "Fat arrow" syntax var f3 = (i: number): number => { return i * i; } -// Return type inferred +// "Fat arrow" syntax with return type inferred var f4 = (i: number) => { return i * i; } -// Return type inferred, one-liner means no return keyword needed +// "Fat arrow" syntax with return type inferred, braceless means no return +// keyword needed var f5 = (i: number) => i * i; // Interfaces are structural, anything that has the properties is compliant with diff --git a/uk-ua/bash-ua.html.markdown b/uk-ua/bash-ua.html.markdown index b7e4a5ba..c6e9ebb1 100644 --- a/uk-ua/bash-ua.html.markdown +++ b/uk-ua/bash-ua.html.markdown @@ -13,13 +13,13 @@ contributors: - ["Etan Reisner", "https://github.com/deryni"] translators: - ["Ehreshi Ivan", "https://github.com/IvanEh"] + - ["Serhii Maksymchuk", "https://github.com/Serg-Maximchuk"] lang: uk-ua --- Bash - командна оболонка unix (unix shell), що також розповсюджувалась як оболонка для операційної системи GNU і зараз використовується як командна оболонка за замовчуванням для Linux i Max OS X. -Почти все нижеприведенные примеры могут быть частью shell-скриптов или исполнены напрямую в shell. Майже всі приклади, що наведені нижче можуть бути частиною shell-скриптів або виконані в оболонці @@ -28,7 +28,7 @@ Bash - командна оболонка unix (unix shell), що також ро ```bash #!/bin/bash # Перший рядок скрипта - це shebang, який вказує системі, як потрібно виконувати -# скрипт. Як ви вже зрозуміли, коментарі починаються з #. Shebang - тоже коментар +# скрипт. Як ви вже зрозуміли, коментарі починаються з #. Shebang - також коментар # Простий приклад hello world: echo Hello world! @@ -123,7 +123,7 @@ fi # Вирази позначаються наступним форматом: echo $(( 10 + 5 )) -# На відмінно від інших мов програмування, Bash - це командна оболонка, а +# На відміну від інших мов програмування, Bash - це командна оболонка, а # отже, працює в контексті поточної директорії ls @@ -135,7 +135,7 @@ ls -l # Показати кожен файл і директорію на окр # Таким чином ми можемо переглянути тільки *.txt файли в поточній директорії: ls -l | grep "\.txt" -# Ви можете перенаправ вхід і вихід команди (stdin, stdout, stderr). +# Ви можете перенаправити вхід і вихід команди (stdin, stdout, stderr). # Наступна команда означає: читати із stdin, поки не зустрінеться ^EOF$, і # перезаписати hello.py наступними рядками (до рядка "EOF"): cat > hello.py << EOF @@ -155,7 +155,7 @@ python hello.py > "output.out" python hello.py 2> "error.err" python hello.py > "output-and-error.log" 2>&1 python hello.py > /dev/null 2>&1 -# Поток помилок перезапише фпйл, якщо цей файл існує +# Потік помилок перезапише файл, якщо цей файл існує # тому, якщо ви хочете дописувати до файлу, використовуйте ">>": python hello.py >> "output.out" 2>> "error.err" @@ -172,7 +172,6 @@ echo "#helloworld" > output.out echo "#helloworld" | cat > output.out echo "#helloworld" | tee output.out >/dev/null -# Подчистить временные файлы с подробным выводом ('-i' - интерактивый режим) # Очистити тимчасові файли з детальним виводом (додайте '-i' # для інтерактивного режиму) rm -v output.out error.err output-and-error.log @@ -194,7 +193,7 @@ case "$VARIABLE" in esac # Цикл for перебирає елементи передані в аргумент: -# Значення $VARIABLE буде напечатано тричі. +# Значення $VARIABLE буде надруковано тричі. for VARIABLE in {1..3} do echo "$VARIABLE" @@ -260,12 +259,11 @@ uniq -d file.txt cut -d ',' -f 1 file.txt # замінити кожне 'okay' на 'great' у файлі file.txt (підтримується regex) sed -i 's/okay/great/g' file.txt -# вивести в stdout все рядки з file.txt, що задовольняють шаблону regex; +# вивести в stdout всі рядки з file.txt, що задовольняють шаблону regex; # цей приклад виводить рядки, що починаються на foo і закінчуються на bar: grep "^foo.*bar$" file.txt # використайте опцію -c, щоб вивести кількість входжень grep -c "^foo.*bar$" file.txt -# чтобы искать по строке, а не шаблону regex, используйте fgrep (или grep -F) # щоб здійснити пошук по рядку, а не по шаблону regex, використовуйте fgrea (або grep -F) fgrep "^foo.*bar$" file.txt diff --git a/visualbasic.html.markdown b/visualbasic.html.markdown index 0371e6f6..f081b907 100644 --- a/visualbasic.html.markdown +++ b/visualbasic.html.markdown @@ -272,11 +272,3 @@ Module Module1 End Module ``` - -## References - -I learnt Visual Basic in the console application. It allowed me to understand the principles of computer programming to go on to learn other programming languages easily. - -I created a more indepth <a href="http://www.vbbootcamp.co.uk/" Title="Visual Basic Tutorial">Visual Basic tutorial</a> for those who would like to learn more. - -The entire syntax is valid. Copy the and paste in to the Visual Basic compiler and run (F5) the program. diff --git a/zh-cn/angularjs-cn.html.markdown b/zh-cn/angularjs-cn.html.markdown new file mode 100644 index 00000000..418a817d --- /dev/null +++ b/zh-cn/angularjs-cn.html.markdown @@ -0,0 +1,710 @@ +--- +category: tool +tool: AngularJS +contributors: + - ["Walter Cordero", "http://waltercordero.com"] +filename: learnangular-cn.html +translators: + - ["Jiang Haiyun", "http://www.atjiang.com"] +lang: zh-cn +--- + +## AngularJS 教程。 + +AngularJS 1.0 版在 2012 年发布。 +Miško Hevery, 一位 Google 员工, 从 2009 年开始开发 AngularJS。 +结果发现这个想法很好,从而该项目现在也被 Google 官方所支持了。 + +AngularJS 是一个 JavaScript 框架。它可以通过一个 "script" 标签添加到一个 HTML 页面中。 +AngularJS 通过指令扩展了 HTML 属性,并且通过表达式将数据绑定到 HTML。 + +## 你应该已经了解了的知识 + +在学习 AngularJS 之前, 你应该对以下知识有了基本的了解: + +- HTML +- CSS +- JavaScript + +```html +// AngularJS 是一个 JavaScript 框架。它是一个用 JavaScript 写的库。 +// AngularJS 以一个 JavaScript 文件的形式发布,并且能通过一个 script 标签添加到一个网页中: +// <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script> + +/////////////////////////////////// +// AngularJS 扩展 HTML + +//AngularJS 通过 ng-directives 扩展 HTML。 +//ng-app 指令定义一个 AngularJS 应用。 +//ng-model 指令将 HTML 控件 (input, select, textarea) 的值绑定到应用的数据上。 +//ng-bind 指令将应用的数据绑定到 HTML 视图上。 +<!DOCTYPE html> +<html> + <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script> + <body> + <div ng-app=""> + <p>Name: <input type="text" ng-model="name"></p> + <p ng-bind="name"></p> + </div> + </body> +</html> + +/* + * 例子解析: + * AngularJS 在网页加载后自动开启。 + * ng-app 指令告诉 AngularJS: <div> 元素是 AngularJS 应用的 "所有者"。 + * ng-model 指令将 input 输入框的值绑定到应用的 name 变量上。 + * ng-bind 指令将 <p> 元素的 innerHTML 绑定到应用的 name 变量上。 +*/ +<tag> 这里是要解析的内容 </tag> + +/////////////////////////////////// +// AngularJS 表达式 + +// AngularJS 表达式写在双括号内: {{ 表达式 }}。 +// AngularJS 表达式采用和 ng-bind 指令一样的方式将数据绑定到 HTML。 +// AngularJS 将在编写表达式的原样位置上 "输出" 数据。 +// AngularJS 表达式非常像 JavaScript 表达式:它们能包含文本,运算符和变量。 +// 例如 {{ 5 + 5 }} 或 {{ firstName + " " + lastName }} +<!DOCTYPE html> +<html> + <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script> + <body> + <div ng-app=""> + <p>My first expression: {{ 5 + 5 }}</p> + </div> + </body> +</html> + +//如果你删除了 ng-app 指令, HTML 将原样显示表达式,不对它进行解析: +<!DOCTYPE html> +<html> + <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script> + <body> + <div> + <p>My first expression: {{ 5 + 5 }}</p> + </div> + </body> +</html> + +// AngularJS 表达式采用和 ng-bind 指令一样的方式将 AngularJS 数据绑定到 HTML。 +<!DOCTYPE html> +<html> +<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script> + <body> + <div ng-app=""> + <p>Name: <input type="text" ng-model="name"></p> + <p>{{name}}</p> + </div> + </body> +</html> + +// AngularJS 的数字类似 JavaScript 的数字: +<div ng-app="" ng-init="quantity=1;cost=5"> + <p>Total in dollar: {{ quantity * cost }}</p> +</div> + +//AngularJS 的字符串类似 JavaScript 的字符串: +<div ng-app="" ng-init="firstName='John';lastName='Doe'"> + <p>The name is <span ng-bind="firstName + ' ' + lastName"></span></p> +</div> + +//AngularJS 的对象类似 JavaScript 的对象: +<div ng-app="" ng-init="person={firstName:'John',lastName:'Doe'}"> + <p>The name is {{ person.lastName }}</p> +</div> + +//AngularJS 的数组类似 JavaScript 的数组: +<div ng-app="" ng-init="points=[1,15,19,2,40]"> + <p>The third result is {{ points[2] }}</p> +</div> + +// 和 JavaScript 表达式一样, AngularJS 表达式能包含文本,运算符和变量。 +// 和 JavaScript 表达式不同, AngularJS 表达式能写在 HTML 内。 +// AngularJS 表达式不支持条件,循环和异常,而 JavaScript 表达式却支持。 +// AngularJS 表达式支持过滤器,而 JavaScript 表达式不支持。 + +/////////////////////////////////// +// AngularJS 指令 + + +//AngularJS 指令使用前缀 ng- 扩展 HTML 属性。 +//ng-app 指令初始化一个 AngularJS 应用。 +//ng-init 指令初始化应用的数据。 +//ng-model 指令将 HTML 控件 (input, select, textarea) 的值绑定到应用的数据上。 +<div ng-app="" ng-init="firstName='John'"> + <p>Name: <input type="text" ng-model="firstName"></p> + <p>You wrote: {{ firstName }}</p> +</div> + +//使用 ng-init 并不常见。你将在有关控制器的章节中学习如何初始化数据。 + +//ng-repeat 指令会重复一个 HTML 元素: +<div ng-app="" ng-init="names=['Jani','Hege','Kai']"> + <ul> + <li ng-repeat="x in names"> + {{ x }} + </li> + </ul> +</div> + +//ng-repeat 指令用在一个对象数组上: +<div ng-app="" ng-init="names=[ +{name:'Jani',country:'Norway'}, +{name:'Hege',country:'Sweden'}, +{name:'Kai',country:'Denmark'}]"> + <ul> + <li ng-repeat="x in names"> + {{ x.name + ', ' + x.country }} + </li> + </ul> +</div> + +// AngularJS 最适合用于数据库 CRUD (Create Read Update Delete) 的应用。 +// 只需设想这些对象都是来自一个数据库的记录。 + +// ng-app 指令定义一个 AngularJS 应用的根元素。 +// ng-app 指令将在页面加载后自动启动(自动初始化)应用。 +// 稍后你将学习如何为 ng-app 设置一个值(如 ng-app="myModule"), 来连接代码模块。 + +// ng-init 指令为一个 AngularJS 应用定义初始值。 +// 通常,你不太使用 ng-init。你会转而使用一个控制器或模块。 +// 你将在稍后学到更多有关控制器和模块的内容。 + +//ng-model 指令将 HTML 控件 (input, select, textarea) 的值绑定到应用的数据上。 +//ng-model 指令还能: +//为应用的数据提供类型验证 (number, email, required)。 +//为应用的数据提供状态信息 (invalid, dirty, touched, error)。 +//为 HTML 元素提供 CSS 类。 +//将 HTML 元素绑定到 HTML 表单。 + +//ng-repeat 指令为集合(一个数组)中的每个元素克隆出 HTML 元素。 + +/////////////////////////////////// +// AngularJS 控制器 + +// AngularJS 控制器控制 AngularJS 应用中的数据。 +// AngularJS 控制器就是常规的 JavaScript 对象。 + +// AngularJS 应用由控制器控制。 +// ng-controller 指令定义应用的控制器。 +// 一个控制器就是一个 JavaScript 对象, 通过标准的 JavaScript 对象构建器创建。 + +<div ng-app="myApp" ng-controller="myCtrl"> + +First Name: <input type="text" ng-model="firstName"><br> +Last Name: <input type="text" ng-model="lastName"><br> +<br> +Full Name: {{firstName + " " + lastName}} + +</div> + +<script> +var app = angular.module('myApp', []); +app.controller('myCtrl', function($scope) { + $scope.firstName = "John"; + $scope.lastName = "Doe"; +}); +</script> + +//应用的解析: + +//AngularJS 应用通过 ng-app="myApp" 定义。该应用运行在 <div> 内。 +//ng-controller="myCtrl" 属性是一个 AngularJS 指令。它定义了一个控制器。 +//myCtrl 函数是一个 JavaScript 函数。 +//AngularJS 将使用一个 $scope 对象来调用控制器。 +//AngularJS 中, $scope 就是该应用对象(应用的变量和函数的所有者)。 +//该控制器在 $scope 内创建了两个属性(即变量 firstName 和 lastName)。 +//ng-model 指令将输入表单项绑定到控制器的属性上(firstName 和 lastName)。 + +//以上的例子演示了一个包含有两个属性 lastName 和 firstName 的控制器。 +//一个控制器也可以有方法(函数的变量): +<div ng-app="myApp" ng-controller="personCtrl"> + +First Name: <input type="text" ng-model="firstName"><br> +Last Name: <input type="text" ng-model="lastName"><br> +<br> +Full Name: {{fullName()}} + +</div> + +<script> +var app = angular.module('myApp', []); +app.controller('personCtrl', function($scope) { + $scope.firstName = "John"; + $scope.lastName = "Doe"; + $scope.fullName = function() { + return $scope.firstName + " " + $scope.lastName; + } +}); +</script> + +//在较大型的应用中, 通常是将控制器代码保存在外部文件中。 +//只需将 <script> </script> 标签之间的代码复制到一个名为 personController.js 的外部文件中: + +<div ng-app="myApp" ng-controller="personCtrl"> + +First Name: <input type="text" ng-model="firstName"><br> +Last Name: <input type="text" ng-model="lastName"><br> +<br> +Full Name: {{firstName + " " + lastName}} + +</div> + +<script src="personController.js"></script> + +// 为方便下个例子使用,我们将创建一个新的控制器文件: +angular.module('myApp', []).controller('namesCtrl', function($scope) { + $scope.names = [ + {name:'Jani',country:'Norway'}, + {name:'Hege',country:'Sweden'}, + {name:'Kai',country:'Denmark'} + ]; +}); + +//将文件保存为 namesController.js: +//然后在一个应用中使用该控制器: + +<div ng-app="myApp" ng-controller="namesCtrl"> + +<ul> + <li ng-repeat="x in names"> + {{ x.name + ', ' + x.country }} + </li> +</ul> + +</div> + +<script src="namesController.js"></script> + +/////////////////////////////////// +// AngularJS 过滤器 + +// 过滤器可以通过一个管道符添加到表达式和指令上。 +// AngularJS 过滤器能用来转换数据: + +- **currency**: 将一个数字格式化成货币格式。 +- **filter**: 从一个数组中选择一组子集元素。 +- **lowercase**: 将一个字符串格式化成小写形式。 +- **orderBy**: 依据一个表达式排序一个数组。 +- **upper**: 将一个字符串格式化成大写形式。 + +//一个过滤器可以通过一个管道符 (|) 及一个过滤器表达式添加到一个表达式上。 +//(在下面的两个例子中,我们将使用前一章中的 person 控制器) +//uppercase 过滤器将字符串格式化成大写格式: +<div ng-app="myApp" ng-controller="personCtrl"> + +<p>The name is {{ lastName | uppercase }}</p> + +</div> + +//lowercase 过滤器将字符串格式化成小写格式: +<div ng-app="myApp" ng-controller="personCtrl"> + +<p>The name is {{ lastName | lowercase }}</p> + +</div> + +//currency 过滤器将一个数字格式化成货币格式: +<div ng-app="myApp" ng-controller="costCtrl"> + +<input type="number" ng-model="quantity"> +<input type="number" ng-model="price"> + +<p>Total = {{ (quantity * price) | currency }}</p> + +</div> + +//一个过滤器可以通过一个管道符 (|) 及一个过滤器表达式添加到一个指令上。 +//orderBy 过滤器根据一个表达式排序一个数组: +<div ng-app="myApp" ng-controller="namesCtrl"> + +<ul> + <li ng-repeat="x in names | orderBy:'country'"> + {{ x.name + ', ' + x.country }} + </li> +</ul> + +<div> + +//一个输入框过滤器可以通过一个管道符 (|) +//以及后跟一个冒号和模式名的 filter 添加到一个指令上。 +//该过滤器从一个数组中选择一个子集: + +<div ng-app="myApp" ng-controller="namesCtrl"> + +<p><input type="text" ng-model="test"></p> + +<ul> + <li ng-repeat="x in names | filter:test | orderBy:'country'"> + {{ (x.name | uppercase) + ', ' + x.country }} + </li> +</ul> + +</div> + +/////////////////////////////////// +// AngularJS AJAX - $http + +//$http 是一个从远程服务器读取数据的 AngularJS 服务。 + +// 以下数据可由一个 web 服务器提供: +// http://www.w3schools.com/angular/customers.php +// **访问 URL 来查看数据格式** + +// AngularJS $http 是一个从 web 服务器上读取数据的核心服务。 +// $http.get(url) 这个函数用来读取服务器数据。 +<div ng-app="myApp" ng-controller="customersCtrl"> + +<ul> + <li ng-repeat="x in names"> + {{ x.Name + ', ' + x.Country }} + </li> +</ul> + +</div> + +<script> +var app = angular.module('myApp', []); +app.controller('customersCtrl', function($scope, $http) { + $http.get("http://www.w3schools.com/angular/customers.php") + .success(function(response) {$scope.names = response.records;}); +}); +</script> + +// 应用解析: + +// AngularJS 应用由 ng-app 定义。该应用运行在一个 <div> 中。 +// ng-controller 指令命名控制器对象。 +// customersCtrl 函数是一个标准的 JavaScript 对象构造器。 +// AngularJS 会使用一个 $scope 和 $http 对象来调用 customersCtrl。 +// $scope 就是该应用对象(应用的变量和函数的所有者)。 +// $http 是一个用于请求外部数据的 XMLHttpRequest 对象。 +// $http.get() 从 http://www.w3schools.com/angular/customers.php 读取 JSON 数据。 +// 如果成功, 该控制器会根据来自服务器的 JSON 数据,在 $scope 中创建一个属性 (names)。 + + +// 向不同的服务器(不同于请求页)请求数据,称作跨站 HTTP 请求。 +// 跨站请求在网站上很普遍。许多网页会从不同的服务器加载 CSS,图片和脚本。 +// 在现代浏览器中,基于安全原因,从脚本内进行跨站 HTTP 请求是被禁止的。 +// 下面的这行代码,已被加入到我们的 PHP 例子中,以便允许跨站访问。 +header("Access-Control-Allow-Origin: *"); + + +/////////////////////////////////// +// AngularJS 表格 + +// 使用 angular 显示表格非常简单: +<div ng-app="myApp" ng-controller="customersCtrl"> + +<table> + <tr ng-repeat="x in names"> + <td>{{ x.Name }}</td> + <td>{{ x.Country }}</td> + </tr> +</table> + +</div> + +<script> +var app = angular.module('myApp', []); +app.controller('customersCtrl', function($scope, $http) { + $http.get("http://www.w3schools.com/angular/customers.php") + .success(function (response) {$scope.names = response.records;}); +}); +</script> + +// 要排序表格,添加一个 orderBy 过滤器: +<table> + <tr ng-repeat="x in names | orderBy : 'Country'"> + <td>{{ x.Name }}</td> + <td>{{ x.Country }}</td> + </tr> +</table> + +// 要显示表格索引值,添加一个带有 $index 的 <td>: +<table> + <tr ng-repeat="x in names"> + <td>{{ $index + 1 }}</td> + <td>{{ x.Name }}</td> + <td>{{ x.Country }}</td> + </tr> +</table> + +// 使用 $even 和 $odd +<table> + <tr ng-repeat="x in names"> + <td ng-if="$odd" style="background-color:#f1f1f1">{{ x.Name }}</td> + <td ng-if="$even">{{ x.Name }}</td> + <td ng-if="$odd" style="background-color:#f1f1f1">{{ x.Country }}</td> + <td ng-if="$even">{{ x.Country }}</td> + </tr> +</table> + +/////////////////////////////////// +// AngularJS HTML DOM + +//AngularJS 有用于将应用的数据绑定到 HTML DOM 元素属性的指令。 + +// ng-disabled 指令将 AngularJS 应用的数据绑定到 HTML 元素的 disabled 属性上。 + +<div ng-app="" ng-init="mySwitch=true"> + +<p> +<button ng-disabled="mySwitch">Click Me!</button> +</p> + +<p> +<input type="checkbox" ng-model="mySwitch">Button +</p> + +</div> + +//应用解析: + +// ng-disabled 指令将应用的 mySwitch 数据绑定到 HTML 按钮的 disabled 属性上。 +// ng-model 指令将 HTML checkbox 元素的值绑定到 mySwitch 的值上。 +// 如果 mySwitch 的值求值为 true,则该按钮将被禁用: +<p> +<button disabled>Click Me!</button> +</p> + +// 如果 mySwitch 的值求值为 false,则该按钮将不会被禁用: +<p> + <button>Click Me!</button> +</p> + +// ng-show 指令显示或隐藏一个 HTML 元素。 + +<div ng-app=""> + +<p ng-show="true">I am visible.</p> + +<p ng-show="false">I am not visible.</p> + +</div> + +// ng-show 指令基于 ng-show 的值显示(或隐藏)一个 HTML 元素。 +// 你可以使用任何能求值成 true 或 false 的表达式: +<div ng-app=""> +<p ng-show="hour > 12">I am visible.</p> +</div> + +/////////////////////////////////// +// AngularJS 事件 + +// AngularJS 有它自己的 HTML 事件指令。 + +// ng-click 指令定义一个 AngularJS 点击事件。 +<div ng-app="myApp" ng-controller="myCtrl"> + +<button ng-click="count = count + 1">Click me!</button> + +<p>{{ count }}</p> + +</div> +<script> +var app = angular.module('myApp', []); +app.controller('myCtrl', function($scope) { + $scope.count = 0; +}); +</script> + +// ng-hide 指令可用于设置一个应用的部分区域的可见性。 +// 值 ng-hide="true" 使得一个 HTML 元素不可见。 +// 值 ng-hide="false" 使得一个 HTML 元素可见。 +<div ng-app="myApp" ng-controller="personCtrl"> + +<button ng-click="toggle()">Toggle</button> + +<p ng-hide="myVar"> +First Name: <input type="text" ng-model="firstName"><br> +Last Name: <input type="text" ng-model="lastName"><br> +<br> +Full Name: {{firstName + " " + lastName}} +</p> + +</div> + +<script> +var app = angular.module('myApp', []); +app.controller('personCtrl', function($scope) { + $scope.firstName = "John", + $scope.lastName = "Doe" + $scope.myVar = false; + $scope.toggle = function() { + $scope.myVar = !$scope.myVar; + }; +}); +</script> + +//应用解析: + +// personController 的第一部分和讲述控制器章节中的一样。 +// 该应用有一个默认属性(一个变量):$scope.myVar = false: +// ng-hide 指令依据 myVar 的值(true 或 false), +// 设置 <p> 元素的可见性,该元素含有两个输入框。 +// 函数 toggle() 将 myVar 在 true 和 false 间进行切换。 +// 值 ng-hide="true" 使得该元素不可见。 + + +// ng-show 指令也能用来设置一个应用的某部分的可见性。 +// 值 ng-show="false" 使得一个 HTML 元素不可见。 +// 值 ng-show="true" 使得一个 HTML 元素可见。 +// 这个例子与上面的一样,但用 ng-show 替代了 ng-hide: +<div ng-app="myApp" ng-controller="personCtrl"> + +<button ng-click="toggle()">Toggle</button> + +<p ng-show="myVar"> +First Name: <input type="text" ng-model="firstName"><br> +Last Name: <input type="text" ng-model="lastName"><br> +<br> +Full Name: {{firstName + " " + lastName}} +</p> + +</div> + +<script> +var app = angular.module('myApp', []); +app.controller('personCtrl', function($scope) { + $scope.firstName = "John", + $scope.lastName = "Doe" + $scope.myVar = true; + $scope.toggle = function() { + $scope.myVar = !$scope.myVar; + } +}); +</script> + +/////////////////////////////////// +// AngularJS 模块 + +// 一个 AngularJS 模块定义一个应用。 +// 模块是一个应用的不同部分所在的一个容器。 +// 模块是应用控制器的一个容器。 +// 控制器总是隶属于一个模块。 + +// 这个应用 ("myApp") 有一个控制器 ("myCtrl"): + +<!DOCTYPE html> +<html> +<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script> +<body> + +<div ng-app="myApp" ng-controller="myCtrl"> +{{ firstName + " " + lastName }} +</div> + +<script> +var app = angular.module("myApp", []); +app.controller("myCtrl", function($scope) { + $scope.firstName = "John"; + $scope.lastName = "Doe"; +}); +</script> + +</body> +</html> + +// 在 AngularJS 应用中通常将模块和控制器放置在 JavaScript 文件中。 +// 在本例中,"myApp.js" 包含了一个应用模块的定义,而 "myCtrl.js" 包含了控制器: + +<!DOCTYPE html> +<html> +<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script> +<body> + +<div ng-app="myApp" ng-controller="myCtrl"> +{{ firstName + " " + lastName }} +</div> + +<script src="myApp.js"></script> +<script src="myCtrl.js"></script> + +</body> +</html> + +//myApp.js +var app = angular.module("myApp", []); + +// 模块定义中的 [] 参数可用来定义依赖的模块。 + +// myCtrl.js +app.controller("myCtrl", function($scope) { + $scope.firstName = "John"; + $scope.lastName= "Doe"; +}); + +// JavaScript 中应该避免使用全局函数。它们会非常容易地被覆盖 +// 或被其它脚本破坏。 + +// AngularJS 脚本通过将所有函数保存在模块内,缓解了这种问题。 + +// 虽然 HTML 应用中通常是将脚本放置在 +// <body> 元素的末尾,但还是推荐你要么在 +// <head> 中要么在 <body> 的开头处加载 AngularJS 库。 + +// 这是因为对 angular.module 的调用只有在库被加载后才能被编译。 + +<!DOCTYPE html> +<html> +<body> +<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script> + +<div ng-app="myApp" ng-controller="myCtrl"> +{{ firstName + " " + lastName }} +</div> + +<script> +var app = angular.module("myApp", []); +app.controller("myCtrl", function($scope) { + $scope.firstName = "John"; + $scope.lastName = "Doe"; +}); +</script> + +</body> +</html> + + +/////////////////////////////////// +// AngularJS 应用 + +// AngularJS 模块定义 AngularJS 应用。 +// AngularJS 控制器控制 AngularJS 应用。 +// ng-app 指令定义该应用,ng-controller 定义该控制器。 +<div ng-app="myApp" ng-controller="myCtrl"> + First Name: <input type="text" ng-model="firstName"><br> + Last Name: <input type="text" ng-model="lastName"><br> + <br> + Full Name: {{firstName + " " + lastName}} +</div> +<script> + var app = angular.module('myApp', []); + app.controller('myCtrl', function($scope) { + $scope.firstName= "John"; + $scope.lastName= "Doe"; + }); +</script> + +// AngularJS 模块定义应用: +var app = angular.module('myApp', []); + +// AngularJS 控制器控制应用: +app.controller('myCtrl', function($scope) { + $scope.firstName= "John"; + $scope.lastName= "Doe"; +}); +``` + +## 来源 & 参考 + +**例子** + +- http://www.w3schools.com/angular/angular_examples.asp + +**参考** + +- http://www.w3schools.com/angular/angular_ref_directives.asp +- http://www.w3schools.com/angular/default.asp diff --git a/zh-cn/c++-cn.html.markdown b/zh-cn/c++-cn.html.markdown index d71aa8d6..87951bc3 100644 --- a/zh-cn/c++-cn.html.markdown +++ b/zh-cn/c++-cn.html.markdown @@ -315,7 +315,7 @@ void Dog::print() const void Dog::~Dog()
{
- cout << "Goodbye " << name << "\n";
+ std::cout << "Goodbye " << name << "\n";
}
int main() {
diff --git a/zh-cn/less-cn.html.markdown b/zh-cn/less-cn.html.markdown new file mode 100644 index 00000000..365a0287 --- /dev/null +++ b/zh-cn/less-cn.html.markdown @@ -0,0 +1,387 @@ +--- +language: less +filename: learnless-cn.less +contributors: + - ["Saravanan Ganesh", "http://srrvnn.me"] +translators: + - ["Jiang Haiyun", "http://www.atjiang.com"] +lang: zh-cn +--- + + +Less是一种CSS预处理器,它增加了诸如变量、嵌套、mixin等功能。 +Less(以及其它预处理器,如[Sass](http://sass-lang.com/))能帮助开发人员编写易维护,DRY (Don't Repeat Yourself) 的代码。 + +```css + + +//单行注释在编译成CSS后会被删除。 + +/* 多行注释将保留. */ + + + +/* 变量 +==============================*/ + + +/* 你可以将一个CSS值(如一个颜色值)保存到变量中。 + 使用'@'符号来创建一个变量。*/ + +@primary-color: #a3a4ff; +@secondary-color: #51527f; +@body-font: 'Roboto', sans-serif; + +/* 你可以在你的样式文件中使用这些变量。 + 现在假如你想修改颜色,你只需修改一次即可。*/ + +body { + background-color: @primary-color; + color: @secondary-color; + font-family: @body-font; +} + +/* 以上将编译成: */ + +body { + background-color: #a3a4ff; + color: #51527F; + font-family: 'Roboto', sans-serif; +} + + +/* 相比于在你的样式文件中逐个修改,这种方式维护性更好。 */ + + + +/* Mixins +==============================*/ + + +/* 如果你要为多个元素编写同样的代码, + 你可能想实现轻松地重用。*/ + +.center { + display: block; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; +} + +/* 你只需简单地将选择子作为样式添加进来就能使用mixin了 */ + +div { + .center; + background-color: @primary-color; +} + +/* 它将编译成: */ + +.center { + display: block; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; +} +div { + display: block; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; + background-color: #a3a4ff; +} + +/* 通过在选择子后添加括号,可以使这些mixin代码不被编译 */ + +.center() { + display: block; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; +} + +div { + .center; + background-color: @primary-color; +} + +/* 将编译成: */ +div { + display: block; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; + background-color: #a3a4ff; +} + + + +/* 嵌套 +==============================*/ + + +/* Less允许你在选择子中嵌套选择子 */ + +ul { + list-style-type: none; + margin-top: 2em; + + li { + background-color: #f00; + } +} + +/* '&'将被替换成父选择子。*/ +/* 你也可以嵌套伪类。 */ +/* 注意过度嵌套将会导致代码难以维护。 + 最佳实践推荐在嵌套时不超过3层。 + 例如: */ + +ul { + list-style-type: none; + margin-top: 2em; + + li { + background-color: red; + + &:hover { + background-color: blue; + } + + a { + color: white; + } + } +} + +/* 编译成: */ + +ul { + list-style-type: none; + margin-top: 2em; +} + +ul li { + background-color: red; +} + +ul li:hover { + background-color: blue; +} + +ul li a { + color: white; +} + + + +/* 函数 +==============================*/ + + +/* Less提供的函数可以用来完成多种任务。 + 考虑以下情况: */ + +/* 函数可以通过其名称及传入其所需的参数来调用。 */ + +body { + width: round(10.25px); +} + +.header { + background-color: lighten(#000, 0.5); +} + +.footer { + background-color: fadeout(#000, 0.25) +} + +/* 编译成: */ + +body { + width: 10px; +} + +.header { + background-color: #010101; +} + +.footer { + background-color: rgba(0, 0, 0, 0.75); +} + +/* 你也可以定义自己的函数。函数非常类似于mixin。 + 当你在函数和mixin之间抉择时, + 记住mixin最适合用来创建CSS而函数更适合于 + 处理那些可能在你的Less代码中使用的逻辑。 + '数学运算符'部分的例子是转成可重用函数的最佳选择。*/ + +/* 该函数计算两数的平均值: */ + +.average(@x, @y) { + @average-result: ((@x + @y) / 2); +} + +div { + .average(16px, 50px); // "调用"mixin + padding: @average-result; // 使用它的"返回"值 +} + +/* 编译成: */ + +div { + padding: 33px; +} + + + +/* 扩展 (继承) +==============================*/ + + +/* 扩展是在选择子间共享属性的一种方法。 */ + +.display { + height: 50px; +} + +.display-success { + &:extend(.display); + border-color: #22df56; +} + +/* 编译成: */ +.display, +.display-success { + height: 50px; +} +.display-success { + border-color: #22df56; +} + +/* 扩展一条CSS语句优于创建一个mixin, + 这是由其组合所有共享相同基样式的类的方式决定的。 + 如果使用mixin完成,其属性将会在调用了该mixin的每条语句中重复。 + 虽然它不至会影响你的工作流,但它会在由Less编译器 + 生成的的文件中添加不必要的代码。*/ + + + +/* 片段与导入 +==============================*/ + + +/* Less允许你创建片段文件。它有助于你的Less代码保持模块化。 + 片段文件习惯上以'_'开头,例如 _reset.css,并被导入到 + 一个将会被编译成CSS的主less文件中。*/ + +/* 考虑以下的CSS,我们将把它们放入一个叫_reset.css的文件中 */ + +html, +body, +ul, +ol { + margin: 0; + padding: 0; +} + +/* Less提供的@import能用来将片段导入到文件中。 + 它与传统的CSS @import语句不同,无需通过 + HTTP请求获取导入文件。Less提取导入文件 + 并将它们与编译后的代码结合起来。 */ + +@import 'reset'; + +body { + font-size: 16px; + font-family: Helvetica, Arial, Sans-serif; +} + +/* 编译成: */ + +html, body, ul, ol { + margin: 0; + padding: 0; +} + +body { + font-size: 16px; + font-family: Helvetica, Arial, Sans-serif; +} + + + +/* 数学运算符 +==============================*/ + + +/* Less提供以下的运算符: +, -, *, /, 和 %。 + 相比于使用你事先手工计算好了的数值,它们 + 对于直接在你的Less文件中计算数值很有用。 + 以下是设置一个两列设计的例子。*/ + +@content-area: 960px; +@main-content: 600px; +@sidebar-content: 300px; + +@main-size: @main-content / @content-area * 100%; +@sidebar-size: @sidebar-content / @content-area * 100%; +@gutter: 100% - (@main-size + @sidebar-size); + +body { + width: 100%; +} + +.main-content { + width: @main-size; +} + +.sidebar { + width: @sidebar-size; +} + +.gutter { + width: @gutter; +} + +/* 编译成: */ + +body { + width: 100%; +} + +.main-content { + width: 62.5%; +} + +.sidebar { + width: 31.25%; +} + +.gutter { + width: 6.25%; +} + + +``` + +## 实践Less + +如果你想在你的浏览器中尝试LESS,参阅: +* [Codepen](http://codepen.io/) +* [LESS2CSS](http://lesscss.org/less-preview/) + +## 兼容性 + +Less可以用于任何项目中,只要你有程序能将它编译成CSS即可。你还需要验证你所使用的CSS是否与你的目标浏览器兼容。 + +[QuirksMode CSS](http://www.quirksmode.org/css/)和[CanIUse](http://caniuse.com) 对于检查兼容性来说都是不错的资源。 + +## 延伸阅读资料 +* [Official Documentation](http://lesscss.org/features/) +* [Less CSS - Beginner's Guide](http://www.hongkiat.com/blog/less-basic/) diff --git a/zh-cn/r-cn.html.markdown b/zh-cn/r-cn.html.markdown index 55a29b11..d576db29 100644 --- a/zh-cn/r-cn.html.markdown +++ b/zh-cn/r-cn.html.markdown @@ -303,7 +303,7 @@ if (4 > 3) { # 定义如下 jiggle <- function(x) { - x + rnorm(x, sd=.1) #add in a bit of (controlled) noise + x = x + rnorm(1, sd=.1) # 添加一点(正态)波动 return(x) } diff --git a/zh-cn/sass-cn.html.markdown b/zh-cn/sass-cn.html.markdown new file mode 100644 index 00000000..985c6470 --- /dev/null +++ b/zh-cn/sass-cn.html.markdown @@ -0,0 +1,585 @@ +--- +language: sass +filename: learnsass-cn.scss +contributors: + - ["Laura Kyle", "https://github.com/LauraNK"] + - ["Sean Corrales", "https://github.com/droidenator"] + - ["Kyle Mendes", "https://github.com/pink401k"] + - ["Keith Miyake", "https://github.com/kaymmm"] +translators: + - ["Jiang Haiyun", "http://www.atjiang.com"] +lang: zh-cn +--- + +Sass是一种CSS扩展语言,它增加了诸如变量、嵌套、mixin等功能。 +Sass(以及其它预处理器,如[Less](http://lesscss.org/)等) 能帮助开发人员编写易维护和 DRY (Don't Repeat Yourself)的代码。 + +Sass有两种不同的语法可选用。SCSS的语法和CSS的相同,但增加了Sass的额外功能。或者Sass(原来的语法),它使用缩进而非大括号和分号。 + +本教程使用SCSS编写。 + +如果你已熟悉CSS3,你可能相对能较快地掌握Sass。它并没有提供任何新的类型属性,而只是提供了一些工具使你能更高效的编写CSS,并且使维护更加容易。 + +```scss + + +// 单行注释当Sass被编译成CSS后会被删除。 + +/* 多行注释将保留. */ + +/* 变量 +============================== */ + + + +/* 你可以将一个CSS值(如一个颜色值)保存到变量中。 +使用'$'符号来创建一个变量。*/ + +$primary-color: #A3A4FF; +$secondary-color: #51527F; +$body-font: 'Roboto', sans-serif; + +/* 你可以在你的样式文件中使用变量。 + 现在假如你想修改颜色,你只需修改一次即可。*/ + +body { + background-color: $primary-color; + color: $secondary-color; + font-family: $body-font; +} + +/* 以上将编译成: */ +body { + background-color: #A3A4FF; + color: #51527F; + font-family: 'Roboto', sans-serif; +} + +/* 相比于在你的样式文件中逐个进行修改,这种方式维护性更好。 */ + + + +/* 控制指令 +============================== */ + +/* Sass允许你使用@if, @else, @for, @while, 和 @each 来控制 + 你的代码如何编译成CSS */ + +/* @if/@else块的行为和你可能预想的会完全相同 */ + +$debug: true !default; + +@mixin debugmode { + @if $debug { + @debug "Debug mode enabled"; + + display: inline-block; + } + @else { + display: none; + } +} + +.info { + @include debugmode; +} + +/* 如果$debug设置为了true, .info 将会显示; 如果设置为false那么 + .info 将不显示。 + +注意: @debug将在命令行中输出调试信息。 +在调试你的SCSS时它对于检查变量很有用。*/ + +.info { + display: inline-block; +} + +/* @for是控制循环,它能遍历区间值。 +它对于设置一组元素的类型特别有用。 +有两种形式,"through"和"to"。前者包括最末那个值, +而后者止于最末那个值。 +*/ + +@for $c from 1 to 4 { + div:nth-of-type(#{$c}) { + left: ($c - 1) * 900 / 3; + } +} + +@for $c from 1 through 3 { + .myclass-#{$c} { + color: rgb($c * 255 / 3, $c * 255 / 3, $c * 255 / 3); + } +} + +/* 将编译成: */ + +div:nth-of-type(1) { + left: 0; +} + +div:nth-of-type(2) { + left: 300; +} + +div:nth-of-type(3) { + left: 600; +} + +.myclass-1 { + color: #555555; +} + +.myclass-2 { + color: #aaaaaa; +} + +.myclass-3 { + color: white; +// SASS automatically converts #FFFFFF to white +} + +/* @while也非常直白: */ + +$columns: 4; +$column-width: 80px; + +@while $columns > 0 { + .col-#{$columns} { + width: $column-width; + left: $column-width * ($columns - 1); + } + + $columns: $columns - 1; +} + +/* 将输出以下CSS: */ + +.col-4 { + width: 80px; + left: 240px; +} + +.col-3 { + width: 80px; + left: 160px; +} + +.col-2 { + width: 80px; + left: 80px; +} + +.col-1 { + width: 80px; + left: 0px; +} + +/* @each函数类似@for, 除了它使用一个列表而不是序列值 +注意: 你指定列表的方式和指定其它变量一样, +用空格作为分隔符。 */ + +$social-links: facebook twitter linkedin reddit; + +.social-links { + @each $sm in $social-links { + .icon-#{$sm} { + background-image: url("images/#{$sm}.png"); + } + } +} + +/* 将输出: */ + +.social-links .icon-facebook { + background-image: url("images/facebook.png"); +} + +.social-links .icon-twitter { + background-image: url("images/twitter.png"); +} + +.social-links .icon-linkedin { + background-image: url("images/linkedin.png"); +} + +.social-links .icon-reddit { + background-image: url("images/reddit.png"); +} + + +/* Mixins +==============================*/ + +/* 如果你发现你要为多个元素编写相同的代码, +你可能想将那些代码保存到一个mixin中。 + +使用'@mixin'指令,再为你的mixin加上一个名称。*/ + +@mixin center { + display: block; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; +} + +/* 你可以通过'@include'及mixin名来调用mixin。 */ + +div { + @include center; + background-color: $primary-color; +} + +/* 将编译成: */ +div { + display: block; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; + background-color: #A3A4FF; +} + +/* 你可以使用mixin来创建一个快捷属性。*/ + +@mixin size($width, $height) { + width: $width; + height: $height; +} + +/* 你可以通过传入width和height参数来调用它。*/ + +.rectangle { + @include size(100px, 60px); +} + +.square { + @include size(40px, 40px); +} + +/* 编译成: */ +.rectangle { + width: 100px; + height: 60px; +} + +.square { + width: 40px; + height: 40px; +} + + + +/* 函数 +============================== */ + + + +/* Sass提供的函数可以用来完成各种各样的任务。 + 考虑以下情况 */ + +/* 函数可以通过其名称及传入其所需的参数来调用 */ +body { + width: round(10.25px); +} + +.footer { + background-color: fade_out(#000000, 0.25); +} + +/* 编译成: */ + +body { + width: 10px; +} + +.footer { + background-color: rgba(0, 0, 0, 0.75); +} + +/* 你也可以定义你自己的函数。函数非常类似于mixin。 + 当你在函数和mixin之间抉择时,记住mixin最适合于创建CSS而函数更适合于 + 处理那些可能在你的Sass代码中使用的逻辑。'数学运算符'部分的例子 + 是转成可重用函数的最理想选择。 */ + +/* 该函数将接收一个目标尺寸大小和父结点尺寸大小,然后计算并 + 返回百分数 */ + +@function calculate-percentage($target-size, $parent-size) { + @return $target-size / $parent-size * 100%; +} + +$main-content: calculate-percentage(600px, 960px); + +.main-content { + width: $main-content; +} + +.sidebar { + width: calculate-percentage(300px, 960px); +} + +/* 编译成: */ + +.main-content { + width: 62.5%; +} + +.sidebar { + width: 31.25%; +} + + + +/* 扩展 (继承) +============================== */ + + + +/* 扩展是在选择子间共享属性的一种方法。 */ + +.display { + @include size(5em, 5em); + border: 5px solid $secondary-color; +} + +.display-success { + @extend .display; + border-color: #22df56; +} + +/* 编译成: */ +.display, .display-success { + width: 5em; + height: 5em; + border: 5px solid #51527F; +} + +.display-success { + border-color: #22df56; +} + +/* 扩展一条CSS语句优于创建一个mixin, + 这是由Sass组合所有共享相同基样式的类的方式决定的。 + 如果使用mixin完成,width, height, 和border将会在 + 调用了该mixin的每条语句中重复。虽然它不至于会影响你的工作流, + 但它会在由Sass编译器生成的的文件中添加不必要的代码。*/ + + +/* 嵌套 +============================== */ + + + +/* Sass允许在选择子中嵌套选择子 */ + +ul { + list-style-type: none; + margin-top: 2em; + + li { + background-color: #FF0000; + } +} + +/* '&'将被父选择子替换。*/ +/* 你也可以嵌套伪类。 */ +/* 注意过度嵌套将导致你的代码难以维护。 +最佳实践推荐在嵌套时不超过3层。 +例如: */ + +ul { + list-style-type: none; + margin-top: 2em; + + li { + background-color: red; + + &:hover { + background-color: blue; + } + + a { + color: white; + } + } +} + +/* 编译成: */ + +ul { + list-style-type: none; + margin-top: 2em; +} + +ul li { + background-color: red; +} + +ul li:hover { + background-color: blue; +} + +ul li a { + color: white; +} + + + +/* 片段与导入 +============================== */ + + + +/* Sass允许你创建片段文件。它有助于你的Sass代码保持模块化。 + 片段文件应该以 '_' 开头,例如 _reset.css。 + 片段不会输出到CSS中。*/ + +/* 考虑以下的CSS,我们会将它们放入一个叫作_reset.css的文件中 */ + +html, +body, +ul, +ol { + margin: 0; + padding: 0; +} + +/* Sass提供的@import能用来将片段导入到文件中。 + 它与传统的CSS @import语句不同,不需要通过 + 另外的HTTP请求来获取导入的文件。 + Sass提取导入文件并将它与编译后的代码结合起来。 */ + +@import 'reset'; + +body { + font-size: 16px; + font-family: Helvetica, Arial, Sans-serif; +} + +/* 编译成: */ + +html, body, ul, ol { + margin: 0; + padding: 0; +} + +body { + font-size: 16px; + font-family: Helvetica, Arial, Sans-serif; +} + + + +/* 占位符选择子 +============================== */ + + + +/* 占位符在创建用于扩展的CSS语句时非常有用。 + 如果你想创建一条只通过@extend使用的CSS语句,你可以利用占位符来实现。 + 占位符以'%'而非'.'或'#'开头。占位符不会出现在编译后的CSS中 */ + +%content-window { + font-size: 14px; + padding: 10px; + color: #000; + border-radius: 4px; +} + +.message-window { + @extend %content-window; + background-color: #0000ff; +} + +/* 编译成: */ + +.message-window { + font-size: 14px; + padding: 10px; + color: #000; + border-radius: 4px; +} + +.message-window { + background-color: #0000ff; +} + + + +/* 数学运算 +============================== */ + + + +/* Sass提供以下的运算符: +, -, *, /, 和 %。它们 + 相比于使用你事先手工计算好了的数值,它们 + 对于直接在你的Sass文件中计算数值很有用。 + 以下是设置一个简单的两列设计的例子。*/ + +$content-area: 960px; +$main-content: 600px; +$sidebar-content: 300px; + +$main-size: $main-content / $content-area * 100%; +$sidebar-size: $sidebar-content / $content-area * 100%; +$gutter: 100% - ($main-size + $sidebar-size); + +body { + width: 100%; +} + +.main-content { + width: $main-size; +} + +.sidebar { + width: $sidebar-size; +} + +.gutter { + width: $gutter; +} + +/* 编译成: */ + +body { + width: 100%; +} + +.main-content { + width: 62.5%; +} + +.sidebar { + width: 31.25%; +} + +.gutter { + width: 6.25%; +} + +``` + +## SASS还是Sass? +该语言的名字,“Sass”,是一个词,不是一个缩写。 +你有没想过Sass是否是一个缩写词?你可能没有,但我反正会告诉你。 +该语言的名字是一个单词,不是一个缩写词。 +由于人们老是将它写成"SASS",语言的作者开玩笑地称它为"Syntactically Awesome StyleSheets"。 + + +## 实践Sass +如果你想在你的浏览器中尝试Sass,参阅[SassMeister](http://sassmeister.com/)。 +你可以选用任一种语法,只需进到设置页然后选择Sass或SCSS。 + + +## 兼容性 +Sass可以用于任何项目中,只要你有程序能将它编译成CSS即可。你还需要验证你所使用的CSS是否与你的目标浏览器兼容。 + +[QuirksMode CSS](http://www.quirksmode.org/css/)和[CanIUse](http://caniuse.com)对于检查兼容性来说都是不错的资源。 + + +## 延伸阅读资料 +* [Official Documentation](http://sass-lang.com/documentation/file.SASS_REFERENCE.html) +* [The Sass Way](http://thesassway.com/) 上提供了教程(初学者-高级)和文章。 |